﻿using System;
using System.Data;
using System.Data.OleDb;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using SHomeWorkshop.LunarConcept.Commands.TextCommands;
using SHomeWorkshop.LunarConcept.Controls;
using SHomeWorkshop.LunarConcept.Converters;
using SHomeWorkshop.LunarConcept.Tools;
using System.Collections.Generic;
using System.Drawing.Text;
using SHomeWorkshop.LunarConcept.Dialogs;
using System.Windows.Markup;
using SHomeWorkshop.LunarConcept.Commands;
using System.Windows.Documents;
using SHomeWorkshop.LunarConcept.Widgets;
using System.IO;
using Microsoft.WindowsAPICodePack.Dialogs;
using Microsoft.WindowsAPICodePack.Shell;
using SHomeWorkshop.LunarConcept.ModifingManager;
using System.Windows.Controls.Ribbon;
using Microsoft.Win32;
using SHomeWorkshop.LunarConcept.Comparers;
using System.Windows.Media.Animation;
using System.Text.RegularExpressions;
using System.Xml;
using LunarSF.SHomeWorkshop.LunarMarkdownEditor;
using System.Data.MoonPdf.Wpf;

namespace SHomeWorkshop.LunarConcept
{
    /// <summary>
    /// 创建时间：2011年12月24日 21:10:41
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：
    ///     MainWindow.xaml的交互逻辑代码。
    /// </summary>
    public partial class MainWindow : Window
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// 构造方法，生成主窗口实例。
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            //绑定自定义命令列表中的项目。
            foreach (CommandBinding cb in Commands.CmdBindings.MainWindowCmdBindingsList)
            {
                this.CommandBindings.Add(cb);
            }

            foreach (CommandBinding cb in Commands.CmdBindings.EditAreaCmdBindingsList)
            {
                this.MainScrollViewer.CommandBindings.Add(cb);
            }

            //绑定系统字体名称列表
            CmbFontNames.ItemsSource = Globals.SystemFontInfosCollection;

            //初始化主编辑器管理器。
            this.editorManager = new EditorManager(this);
            this.MainScrollViewer.Content = this.editorManager;

            //要立即挂接上去，否则自定义的“PageDown、PageUp”按键行为不起作用。
            this.MainScrollViewer.MainEditorManager = this.editorManager;

            this.editorManager.MouseLeftButtonDroped +=
                new EventHandler<Widgets.MouseLeftButtonDraggingEventArgs>(editorManager_MouseLeftButtonDroped);
            this.editorManager.WidgetControlerMoved +=
                new EventHandler<Widgets.MouseLeftButtonDraggingEventArgs>(editorManager_WidgetControlerMoved);
            this.editorManager.WidgetsMoved +=
                new EventHandler<Widgets.MouseLeftButtonDraggingEventArgs>(editorManager_WidgetsMoved);
            this.editorManager.MainSelectedPageChanged +=
                new EventHandler<MainSelectedPageEditorChangedEventArgs>(editorManager_MainSelectedPageChanged);
            this.editorManager.MainSelectedWidgetChanged +=
                new EventHandler<MainSelectedWidgetChangedEventArgs>(editorManager_MainSelectedWidgetChanged);
            this.editorManager.DocumentOpened += new EventHandler<EventArgs>(editorManager_DocumentOpened);

            SvOutLine.Background = this.editorManager.DocumentBackground;
            this.editorManager.DocumentBackgroundChanged += editorManager_DocumentBackgroundChanged;

            Binding scaleBinding = new Binding("Value");
            scaleBinding.Converter = new Converters.ScaleValueConverter();
            scaleBinding.Source = SliderOfScale;

            BindingOperations.SetBinding(this.editorManager.ScaleTransform, ScaleTransform.ScaleXProperty, scaleBinding);
            BindingOperations.SetBinding(this.editorManager.ScaleTransform, ScaleTransform.ScaleYProperty, scaleBinding);

            //读取“最近使用的文档”列表。
            RecentFileItem.ReadRecentFilesFromXmlFile();

            //载入常用图标
            this.ListInCommonUseImages();

            //初始化数据库。
            this.InitializeDataBase();

            //扩展跨页演示时显示可演示区域。
            this.presentationAdorner = new Adorners.PresentationAdorner(this.MainScrollViewer) { Visibility = System.Windows.Visibility.Collapsed, };
            this.AdonerOfMainScrollViewer.AdornerLayer.Add(this.presentationAdorner);

            #region 列出所有可用字体。废弃。会导致界面响应速度慢到令人无法忍受。

            //InstalledFontCollection clsInstalledFontCollection = new InstalledFontCollection();
            //System.Drawing.FontFamily[] affInstalledFont = clsInstalledFontCollection.Families;

            //StringBuilder sb = new StringBuilder();
            //foreach (System.Drawing.FontFamily f in affInstalledFont)
            //{
            //    ComboFontItem cfi = new ComboFontItem(f.Name, new System.Windows.Media.FontFamily(f.Name));
            //    CmbFontNames.Items.Add(cfi);
            //}

            //// 注意：上面使用的是System.Drawing下的FontFamily类，
            //// 而下面使用的是System.Window.Media下的FontFamily。
            //// 好不容易才找到如何解决问题的办法。
            //LanguageSpecificStringDictionary fontDics = this.FontFamily.FamilyNames;
            //if (fontDics.ContainsKey(XmlLanguage.GetLanguage("zh-cn")))
            //{
            //    string fontName = null;
            //    if (fontDics.TryGetValue(XmlLanguage.GetLanguage("zh-cn"), out fontName))
            //    {
            //        Globals.SysFontFamily = fontName;
            //    }
            //}

            // 字体框和字号框的初始化老造成意外问题。
            //if (cbFont.Items.Contains(Globals.SysFontFamily))
            //{
            //    cbFont.SelectedItem = Globals.SysFontFamily;
            //}
            //cbFontSize.SelectedIndex = 2;//字号默认是12，索引是2。

            #endregion

            //载入命令列表。
            ListTextCommands();

            CbxQuickCommandBox.Background = Globals.TextCommandInputBoxBackground;

            //挂接格式刷“格式化完成”事件。
            //用户可以点击“格式刷按钮”主动结束“格式化状态”；也可以等待从部件→页面编辑器→页面管理器→主窗口
            //    一层层传递上来的这个事件来结束。
            editorManager.WidgetFormated += new EventHandler<WidgetFormatedEventArgs>(editorManager_WidgetFormated);

            editorManager.AutoNumberRefreshed += new EventHandler<AutoNumberRefreshedEventArgs>(editorManager_AutoNumberRefreshed);

            workspaceManager = new WorkspaceManager(this);

        }

        #endregion

        #region 字段与属性===================================================================================================

        private EditorManager editorManager;
        /// <summary>
        /// [只读]主编辑器管理器。
        /// </summary>
        public EditorManager EditorManager
        {
            get { return editorManager; }
        }

        public static readonly EnableBrushConverter enableConverter = new EnableBrushConverter();

        /// <summary>
        /// 放大镜控制板。
        /// </summary>
        private Popup magnifierControlPanel;

        private MousePointInfo mouseInfo = new MousePointInfo();
        /// <summary>
        /// 鼠标指针位置。
        /// </summary>
        public MousePointInfo MouseInfo
        {
            get
            {
                return this.mouseInfo;
            }
            set
            {
                this.mouseInfo = value;
            }
        }

        private int refreshOutLineViewRequestionCount = 0;
        /// <summary>
        /// 刷新“大纲视图”的请求的数目。
        /// 
        /// 目的是合并刷新操作，减少刷新的次数（例如：大纲视图处于隐藏状态时就没必要刷新）。
        /// </summary>
        public int RefreshOutLineViewRequestionCount
        {
            get { return refreshOutLineViewRequestionCount; }
        }

        private int refreshPageViewRequestionCount = 0;
        /// <summary>
        /// 刷新“页面视图”的请求的数目。
        /// 
        /// 目的是合并刷新操作，减少刷新的次数（例如：页面视图处于隐藏状态时就没必要刷新）。
        /// </summary>
        public int RefreshPageViewRequestionCount
        {
            get { return refreshPageViewRequestionCount; }
        }

        private Adorners.PresentationAdorner presentationAdorner;

        #endregion

        #region 方法=========================================================================================================

        /// <summary>
        /// 控件模板中定义的某个样式中使用。禁用此按钮对按下Enter键的行为。
        /// </summary>
        private void Button_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                e.Handled = true;
            }
        }

        private void btnDeleteCustomWidgetsItem_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("　　删除数据库的记录将不可恢复，真的要继续吗？",
                Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
            if (result != MessageBoxResult.Yes) return;

            Globals.GlobalConnection.Open();
            DataTable widgetsSetTable = Globals.GlobalDataSetIn.Tables["WidgetsSet"];

            string idString = (sender as Button).Tag.ToString();

            string insertStr = "DELETE FROM WidgetsSet WHERE id=" + idString;
            OleDbCommand myCommand = new OleDbCommand(insertStr, Globals.GlobalConnection);
            myCommand.ExecuteNonQuery();

            //删除数据库记录后，再删除内存数据集中的记录。
            //由于采用了数据绑定，当内存数据集中的记录被删除后，主界面也会相应改变。
            //ID号不会重复，因此不必使用倒序删除。
            for (int i = 0; i < widgetsSetTable.Rows.Count; i++)
            {
                if (widgetsSetTable.Rows[i]["ID"].ToString() == idString)
                {
                    widgetsSetTable.Rows.RemoveAt(i);
                    break;
                }
            }

            Globals.GlobalConnection.Close();
        }

        /// <summary>
        /// 根据数据库中的条目生成页面或部件，粘贴到文档中。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPasteCustomWidgets_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string idString = (sender as Button).Tag.ToString();

                DataTable exTable = Globals.GlobalDataSetIn.Tables["WidgetsSet"];
                foreach (DataRow row in exTable.Rows)
                {
                    if (row["ID"].ToString() == idString)
                    {
                        //Clipboard.SetText(row["ContentText"].ToString());
                        string result = Commands.PasteCommand.Execute(row["ContentText"].ToString());
                        if (result == string.Empty)
                        {
                            string recordDefFontSizeText = row["DefaultFontSize"].ToString();
                            if (string.IsNullOrEmpty(recordDefFontSizeText))
                            {
                                LunarMessage.Warning("　　请检查粘贴的部件是否存在错位或变形。\r\n\r\n" +
                                    "　　被粘贴的部件入库时未记录当时的默认字号。\r\n" +
                                    "　　入库时所在文档的默认字号与当前文档的默认字号不匹配可能会造成部件错位或变形。");
                            }
                            else
                            {
                                double recordDefFontSize = double.Parse(recordDefFontSizeText);
                                if (recordDefFontSize != this.editorManager.DefaultFontSize)
                                {
                                    LunarMessage.Warning(string.Format("　　部件存入数据库时所在文档的默认字号【{0}】与当前文档的默认字号【{1}】不匹配，" +
                                        "这可能会造成部件变形。\r\n\r\n" +
                                        "　　如有必要，请尝试使用“功能区→格式→字体→字号框”来调整粘贴的这些部件的字号或更改当前文档默认字号。",
                                        recordDefFontSize, this.editorManager.DefaultFontSize));
                                }
                            }
                        }
                        else
                        {
                            LunarMessage.Warning(result);
                        }
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("　　发生意外，未能向剪贴板写入文本！系统剪贴板可能被其它程序占用。" +
                    "异常信息如下：\r\n" +
                    ex.Message + "\r\n" + ex.StackTrace, Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            MessageBox.Show("　　发生意外错误，未能将数据库中的自定义部件粘贴到指定位置！", Globals.AppName,
                MessageBoxButton.OK, MessageBoxImage.Warning);
        }

        void editorManager_DocumentBackgroundChanged(object sender, DocumentBackgroundChangedEventArgs e)
        {
            //刷新“大纲视图”背景色。
            if (SvOutLine != null && e.NewDocumentBackground != null)
                SvOutLine.Background = e.NewDocumentBackground;

            //非强制刷新“大纲视图”
            this.RefreshOutlineView(false);
        }

        /// <summary>
        /// 列出所有可用图像（常用图像）。
        /// </summary>
        private void ListInCommonUseImages()
        {
            string inCommonUseImagesRootPath = Globals.PathOfUserDirectory + "常用图像";
            if (System.IO.Directory.Exists(inCommonUseImagesRootPath))
            {
                ListInCommonUseImages(inCommonUseImagesRootPath);
            }

            //支持双图标库位置。二○一三年六月十二日
            inCommonUseImagesRootPath = Globals.InstalledPath + "常用图像";
            if (System.IO.Directory.Exists(inCommonUseImagesRootPath))
            {
                ListInCommonUseImages(inCommonUseImagesRootPath);
            }
        }

        private void ListInCommonUseImages(string inCommonUseImagesRootPath)
        {
            string[] inCommonUseImagesSubPaths = System.IO.Directory.GetDirectories(inCommonUseImagesRootPath);

            //如何排序？
            Array.Sort<string>(inCommonUseImagesSubPaths);

            foreach (string inCommonUseImagesSubPath in inCommonUseImagesSubPaths)
            {
                TvInCommonUseImages.Items.Add(new ImageItem(inCommonUseImagesSubPath));
            }

            if (TvInCommonUseImages.Items.Count > 0)
            {
                TreeViewItem item = TvInCommonUseImages.Items[0] as TreeViewItem;
                if (item != null)
                {
                    item.ExpandSubtree();
                }
            }
        }

        /// <summary>
        /// 切换右侧常用图标工具栏的显示与隐藏状态。
        /// </summary>
        private void ImgShowRightTools_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (GRTools.Width.Value <= 20)
            {
                GRTools.Width = new GridLength(300);
            }
            else
            {
                GRTools.Width = new GridLength(10);
            }
            MainScrollViewer.Focus();
        }

        private void ImgShowLeftTools_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (GLTools.Width.Value <= 20)
            {
                GLTools.Width = new GridLength(300);
                RefreshOutlineView();//刷新大纲视图
                RefreshPageView();
            }
            else if (GLTools.Width.Value > 20 && GLTools.Width.Value < this.ActualWidth - 20)
            {
                GLTools.Width = new GridLength(this.ActualWidth - 20);
                RefreshOutlineView();//刷新大纲视图
                RefreshPageView();
            }
            else
            {
                GLTools.Width = new GridLength(10);
            }
            MainScrollViewer.Focus();
        }

        /// <summary>
        /// 初始化数据库。
        /// </summary>
        private void InitializeDataBase()
        {
            // 检查用户数据目录是否存在，检查用户数据库文件是否存在，若不存在，则尝试复制一个。
            if (System.IO.Directory.Exists(Globals.PathOfUserDirectory))
            {
                if (System.IO.File.Exists(Globals.PathOfDataBase) == false)
                {
                    if (System.IO.File.Exists(Globals.InstalledPath + "\\LunarConcept.mdb"))
                    {
                        System.IO.File.Copy(Globals.InstalledPath + "\\LunarConcept.mdb", Globals.PathOfDataBase);
                        System.Windows.MessageBox.Show("　　数据库初始化完成！文件位置在：\r\n" + Globals.PathOfDataBase,
                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                }
            }

            if (System.IO.File.Exists(Globals.PathOfDataBase))
            {
                //"SELECT TOP 10 * FROM WidgetsSet ORDER BY ID"
                Globals.GlobalDataAdapter = new OleDbDataAdapter
                        ("SELECT TOP 100 * FROM WidgetsSet ORDER BY ID",
                        "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"" + Globals.PathOfDataBase + "\"");

                Globals.GlobalDataAdapter.Fill(Globals.GlobalDataSetIn, "WidgetsSet");

                Globals.GlobalConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\""
                    + Globals.PathOfDataBase + "\"");

                LBUserCustomWidgetsList.DataContext = Globals.GlobalDataSetIn;
            }
        }

        /// <summary>
        /// 准备右键拖动页面。
        /// </summary>
        private void MainScrollViewer_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.mouseInfo.DraggingType = Enums.PageDraggingType.MovePages;
            this.mouseInfo.RightButtonPreviewPoint = e.GetPosition(this.MainScrollViewer);

            //这个比较特殊，名实不符。
            this.mouseInfo.RightButtonPoint = new Point(this.MainScrollViewer.HorizontalOffset,
                this.MainScrollViewer.VerticalOffset);
        }

        /// <summary>
        /// 取消右键拖动页面。
        /// </summary>
        private void MainScrollViewer_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (this.mouseInfo.DraggingType == Enums.PageDraggingType.MovePages)
            {
                Point newPoint = e.GetPosition(this.MainScrollViewer);
                if (Math.Abs(newPoint.X - this.mouseInfo.RightButtonPreviewPoint.X) > 4 ||
                    Math.Abs(newPoint.Y - this.mouseInfo.RightButtonPreviewPoint.Y) > 4)//右键按下与弹起时距离够大才是拖动页面。
                {
                    e.Handled = true;//取消页面右键菜单。
                }
            }

            this.mouseInfo.DraggingType = Enums.PageDraggingType.SelectWidgets;
        }

        /// <summary>
        /// 处理鼠标右键拖动页面。
        /// </summary>
        private void MainScrollViewer_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (this.mouseInfo.DraggingType != Enums.PageDraggingType.MovePages) return;

            Point newPoint = e.GetPosition(this.MainScrollViewer);

            if ((e.MouseDevice.RightButton & MouseButtonState.Pressed) > 0)
            {
                this.MainScrollViewer.ScrollToHorizontalOffset(this.mouseInfo.RightButtonPoint.X
                    - (newPoint.X - this.mouseInfo.RightButtonPreviewPoint.X));
                this.MainScrollViewer.ScrollToVerticalOffset(this.mouseInfo.RightButtonPoint.Y
                    - (newPoint.Y - this.mouseInfo.RightButtonPreviewPoint.Y));
            }
        }

        void editorManager_AutoNumberRefreshed(object sender, AutoNumberRefreshedEventArgs e)
        {
            this.refreshOutLineViewRequestionCount++;//此值在刷新一次大纲视图后即会归零。

            if (GLTools.Width.Value <= 10)
            {
                return;
            }

            RefreshOutlineView();
        }

        /// <summary>
        /// 刷新大纲视图。
        /// </summary>
        public void RefreshOutlineView(bool forceRefresh = false)
        {
            if (forceRefresh == false)
            {
                if (this.refreshOutLineViewRequestionCount <= 0) return;
            }

            OutLineListBox.Items.Clear();

            List<List<Widgets.TextArea>> textAreaLists = new List<List<Widgets.TextArea>>();
            foreach (UIElement peUI in this.editorManager.Children)
            {
                PageEditor pe = peUI as PageEditor;
                if (pe == null) continue;

                List<Widgets.TextArea> textAreaList = pe.GetAllTextAreaWidgets();
                textAreaLists.Add(textAreaList);
            }

            if (textAreaLists.Count <= 0) return;

            foreach (List<Widgets.TextArea> textAreaList in textAreaLists)
            {
                if (textAreaList == null || textAreaList.Count <= 0) continue;

                foreach (Widgets.TextArea tw in textAreaList)
                {
                    if (tw.MasterEditor == null) continue;
                    if (tw.MasterEditor.MasterManager == null) continue;
                    if (tw.TitleLevel == Enums.TitleStyle.Normal) continue;

                    OutLineItem newItem = new OutLineItem()
                    {
                        MasterManager = tw.MasterEditor.MasterManager,
                        MasterPageID = tw.MasterEditor.Id,
                        MasterWidgetID = tw.Id
                    };

                    newItem.BuildItem();

                    newItem.MouseDoubleClick += new MouseButtonEventHandler(newItem_MouseDoubleClick);
                    newItem.KeyDown += new KeyEventHandler(newItem_KeyDown);

                    OutLineListBox.Items.Add(newItem);
                }
            }

            this.refreshOutLineViewRequestionCount = 0;
        }

        /// <summary>
        /// 刷新页面视图。
        /// </summary>
        public void RefreshPageView()
        {
            refreshPageViewRequestionCount++;

            if (GLTools.Width.Value < 10)
            {
                return;
            }

            RefreshPageViewItems();
        }

        private void RefreshPageViewItems()
        {
            PageViewListBox.Items.Clear();

            if (refreshPageViewRequestionCount <= 0) return;

            if (this.editorManager == null) return;

            List<PageEditor> peList = this.editorManager.GetAllPageEditors();
            foreach (PageEditor pe in peList)
            {
                PageViewItem pvi = new PageViewItem();
                pvi.MasterManager = this.editorManager;
                pvi.MasterPageID = pe.Id;
                pvi.BuildItem();
                PageViewListBox.Items.Add(pvi);
            }

            refreshPageViewRequestionCount = 0;
        }

        void editorManager_DocumentOpened(object sender, EventArgs e)
        {
            this.CTGWidgetFormContextualTabGroup.Visibility =
                //this.CTGOutBorderFormContextualTabGroup.Visibility =
                this.CTGRectangleWidgetColorSolution.Visibility =
                this.CTGTriangleFormTabGroup.Visibility =
                this.CTGEllipseColorSolution.Visibility = Visibility.Collapsed;

            this.refreshPageViewRequestionCount++;
            this.refreshOutLineViewRequestionCount++;
        }

        void newItem_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                JumpToWidgetFromOutlineItem(sender as OutLineItem);
            }
        }

        void newItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            OutLineItem oli = sender as OutLineItem;
            JumpToWidgetFromOutlineItem(oli);
        }

        private void JumpToWidgetFromOutlineItem(OutLineItem oli)
        {
            if (oli == null) return;

            if (oli.MasterManager == null) return;
            if (string.IsNullOrEmpty(oli.MasterPageID)) return;

            PageEditor pe = oli.MasterManager.GetPageEditor(oli.MasterPageID);
            if (pe == null) return;

            if (string.IsNullOrEmpty(oli.MasterWidgetID)) return;
            Widgets.Widget w = pe.GetWidget(oli.MasterWidgetID);
            if (w == null) return;

            w.SelectOnlySelf();

            if (GRMainColumnArea.Width.Value < 300)
            {
                GLTools.Width = new GridLength(300);//缩小左工具栏
            }

            LunarMessage.Warning(Globals.MainWindow.TryToShowWidgetInScrollViewer(w));
        }

        /// <summary>
        /// 在状态条上显示一个链接，此链接用以打开此部件类型对应的帮助文档。
        /// </summary>
        void editorManager_MainSelectedWidgetChanged(object sender, MainSelectedWidgetChangedEventArgs e)
        {
            if (e.NewMainSelectedWidget == null)
            {
                BDWidgetHelpLinkArea.Child = null;
                CTGWidgetFormContextualTabGroup.Visibility =
                    //CTGOutBorderFormContextualTabGroup.Visibility =
                    CTGRectangleWidgetColorSolution.Visibility =
                    CTGEllipseColorSolution.Visibility = Visibility.Collapsed;
                return;
            }
            else
            {
                CTGEllipseColorSolution.Visibility = Visibility.Visible;
            }

            Widgets.RhombWidget rw = e.NewMainSelectedWidget as Widgets.RhombWidget;
            if (rw != null)
            {
                CTGWidgetFormContextualTabGroup.Visibility = Visibility.Visible;
            }
            else
            {
                CTGWidgetFormContextualTabGroup.Visibility = Visibility.Collapsed;
            }

            //Widgets.ContentWidget contentWidget = e.NewMainSelectedWidget as Widgets.ContentWidget;
            //if (contentWidget != null)
            //{
            //    CTGOutBorderFormContextualTabGroup.Visibility = Visibility.Visible;
            //}
            //else
            //{
            //    CTGOutBorderFormContextualTabGroup.Visibility = Visibility.Collapsed;
            //}

            Widgets.RectangleWidget rectWidget = e.NewMainSelectedWidget as Widgets.RectangleWidget;
            if (rectWidget != null)
            {
                CTGRectangleWidgetColorSolution.Visibility = Visibility.Visible;
            }
            else
            {
                CTGRectangleWidgetColorSolution.Visibility = Visibility.Collapsed;
            }

            Widgets.EllipseWidget ew = e.NewMainSelectedWidget as Widgets.EllipseWidget;
            if (rectWidget != null || ew != null)
            {
                CTGEllipseColorSolution.Visibility = Visibility.Visible;
            }
            else
            {
                CTGEllipseColorSolution.Visibility = Visibility.Collapsed;
            }

            Widgets.TriangleWidget tw = e.NewMainSelectedWidget as Widgets.TriangleWidget;
            if (tw != null)
            {
                CTGTriangleFormTabGroup.Visibility = Visibility.Visible;
            }
            else
            {
                CTGTriangleFormTabGroup.Visibility = Visibility.Collapsed;
            }

            TextBlock widgetHelpTextBlock = new TextBlock()
            {
                Text = e.NewMainSelectedWidget.WidgetClassLocalName + "...",
                Tag = e.NewMainSelectedWidget.GetType().Name,
                ToolTip = "点击显示帮助",
            };

            widgetHelpTextBlock.TextDecorations.Add(TextDecorations.Underline);
            widgetHelpTextBlock.MouseLeftButtonUp +=
                new MouseButtonEventHandler(widgetHelpTextBlock_MouseLeftButtonUp);

            BDWidgetHelpLinkArea.Child = widgetHelpTextBlock;

            //刷新大纲视图中对应项。
            foreach (OutLineItem oli in OutLineListBox.Items)
            {
                if (oli.MasterWidgetID == e.NewMainSelectedWidget.Id)
                {
                    OutLineListBox.SelectedItem = oli;
                    break;
                }
            }

            //刷新查找结果中的对应项。
            foreach (FindResultItem fri in LbxOfFindResults.Items)
            {
                if (fri.WidgetId == e.NewMainSelectedWidget.Id)
                {
                    LbxOfFindResults.SelectedItem = fri;
                }
            }
        }

        void widgetHelpTextBlock_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            string widgetName = (sender as TextBlock).Tag as string;
            LunarMessage.Warning(Commands.ShowHelpCommand.ShowHelpPage(widgetName));
        }

        /// <summary>
        /// 这个事件处理器用于添加各种线型部件（调用相应的自定义命令来实现）。
        /// 
        /// PageEditor会根据所在的父EditorManager的MouseDraggingType属性值来决定自己的行为：
        /// 
        /// ①如果正在“拖动部件”或“拖动部件控制点”，那么，
        ///     PageEditor会触发“WidgetControlerMoved”事件或“WidgetMoved”事件，
        ///     ——随即引发EditorManager的同名事件
        ///     ——此时，本事件（MouseLeftButtonDroped）不会被触发
        /// ②如果PageEditor正在“添加线型部件”，则会触发本事件（事件参数中会决定添加何种线型部件）
        ///     ——会触发EditorManager的同名事件，此事件在MainWindow.Xaml.cs中处理（调用自定义命令进行实际操作）
        /// </summary>
        void editorManager_MouseLeftButtonDroped(object sender, Widgets.MouseLeftButtonDraggingEventArgs e)
        {
            if (e == null || e.MasterPageEditor == null) return;

            string result = string.Empty;

            switch (e.DraggingType)
            {
                case Enums.PageDraggingType.InsertStraitLine:
                    {
                        result = Commands.InsertStraitLineWidgetCommand.Execute(e);
                        break;
                    }
                case Enums.PageDraggingType.InsertBezierLine:
                    {
                        result = Commands.InsertBezierLineWidgetCommand.Execute(e);
                        break;
                    }
                case Enums.PageDraggingType.InsertPolyLine:
                    {
                        result = Commands.InsertPolyLineWidgetCommand.Execute(e);
                        break;
                    }
                case Enums.PageDraggingType.InsertEllipse:
                    {
                        result = Commands.InsertEllipseWidgetCommand.Execute(e);
                        break;
                    }
                case Enums.PageDraggingType.InsertRectangle:
                    {
                        result = Commands.InsertRectangleWidgetCommand.Execute(e);
                        break;
                    }
                case Enums.PageDraggingType.InsertRhomb:
                    {
                        result = Commands.InsertRhombWidgetCommand.Execute(e);
                        break;
                    }
                case Enums.PageDraggingType.InsertTriangle:
                    {
                        result = Commands.InsertTriangleWidgetCommand.Execute(e);
                        break;
                    }
                case Enums.PageDraggingType.InsertBracket:
                    {
                        result = Commands.InsertBracketWidgetCommand.Execute(e);
                        break;
                    }
                case Enums.PageDraggingType.InsertBezierLineRelation:
                case Enums.PageDraggingType.InsertPolyLineRelation:
                case Enums.PageDraggingType.InsertStraitLineRelation:
                    {
                        result = Commands.InsertRelationCommand.Execute(e);
                        break;
                    }
                    //TODO: 其它线型部件的“插入命令”调用应在此处添加。
            }

            if (editorManager.ContinueInsertWidget == false)
            {
                UnCheckInsertLineWidgetToggleButtons(null);
                editorManager.MouseDraggingType = Enums.PageDraggingType.None;
            }

            if (result != string.Empty)
            {
                MessageBox.Show(result, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        void editorManager_WidgetControlerMoved(object sender, Widgets.MouseLeftButtonDraggingEventArgs e)
        {
            if (e == null || e.MasterPageEditor == null) return;

            switch (e.DraggingType)
            {
                case Enums.PageDraggingType.MoveLineWidgetControler:
                    {
                        Commands.MoveWidgetControlerCommand.Execute(e);
                        break;
                    }
            }
        }

        /// <summary>
        /// 格式化完成事件。
        /// </summary>
        void editorManager_WidgetFormated(object sender, WidgetFormatedEventArgs e)
        {
            this.RTBtnFormatBrush.IsChecked = false;
            this.editorManager.FormatBrush = null;//取消格式刷的格式化状态。
        }

        void editorManager_WidgetsMoved(object sender, Widgets.MouseLeftButtonDraggingEventArgs e)
        {
            if (e == null || e.MasterPageEditor == null) return;

            switch (e.DraggingType)
            {
                case Enums.PageDraggingType.MoveWidgets:
                    {
                        KeyStates ksLeftShift = Keyboard.GetKeyStates(Key.LeftShift);
                        KeyStates ksRightShift = Keyboard.GetKeyStates(Key.RightShift);

                        bool isShift = false;
                        if ((ksLeftShift & KeyStates.Down) > 0 || (ksRightShift & KeyStates.Down) > 0)
                        {
                            isShift = true;
                        }

                        KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
                        KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);

                        bool isCtrl = false;
                        if ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0)
                        {
                            isCtrl = true;
                        }

                        if (isCtrl == false)
                        {
                            Commands.MoveWidgetsCommand.Execute(e);
                        }
                        else
                        {
                            if (isShift == false)//避免与“按四正四隅八个方向移动部件”冲突
                            {
                                Commands.MoveWidgetsAndBuildCopiesCommand.Execute(e);
                            }
                        }

                        break;
                    }
            }
        }

        /// <summary>
        /// 主要功能：鼠标中键点击使主窗口最大化/恢复。
        /// </summary>
        private void RibbonWindow_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if ((e.MiddleButton & MouseButtonState.Pressed) > 0)
            {
                if (this.WindowState != WindowState.Maximized)
                {
                    this.WindowState = WindowState.Maximized;
                }
                else
                {
                    this.WindowState = WindowState.Normal;
                }
            }
        }

        //禁用Ribbon控件的鼠标右键事件，避免弹出英文的右键上下文菜单。
        private void Ribbon_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
        }

        private void RQBtnHelp_Click(object sender, RoutedEventArgs e)
        {
            ShowHelpFile();
        }

        /// <summary>
        /// 显示帮助文档。
        /// </summary>
        private static void ShowHelpFile()
        {
            Commands.ShowHelpCommand.Execute();
        }

        /// <summary>
        /// 关闭窗口前检查是否需要保存文档，是否需要进行其它配置等等。
        /// </summary>
        private void RibbonWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //总是记录，避免多重代码。
            Properties.Settings.Default.StartWindowLocationSetting = this.RestoreBounds;
            Properties.Settings.Default.Save();

            if (CloseDocument() != true) e.Cancel = true;
        }

        internal bool CloseDocument()
        {
            if (PageCommentEditor.IsModified || PageCommentEditor.Document.UndoStack.IsOriginalFile == false)//多加一道判断，保险一些。
            {
                PageEditor mainPe = editorManager.GetMainSelectedPageEditor();
                if (mainPe != null)
                {
                    UpdatePageCommentText(mainPe);
                }
            }

            if (editorManager.IsModified)
            {
                MessageBoxResult result = MessageBox.Show("　　当前文档已被修改，是否需要保存？",
                    Globals.AppName, MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
                switch (result)
                {
                    case MessageBoxResult.Yes:
                        {
                            string saveResult = Commands.SaveDocumentCommand.Execute();

                            if (saveResult == Commands.SaveDocumentCommand.CancelSaveMessage)
                            {
                                return true;
                            }
                            else if (saveResult != string.Empty)
                            {
                                MessageBox.Show("　　未能保存当前文档。异常信息如下：\r\n" + saveResult,
                                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);

                                return false;
                            }
                            else return true;
                        }
                    case MessageBoxResult.No:
                        {
                            return true;//直接关闭。
                        }
                    default: //MessageBoxResult.Cancel:
                        {
                            return false;//取消“关闭”操作。
                        }
                }
            }
            else return true;
        }

        #endregion

        /// <summary>
        /// 清除指定的“添加线型部件”按钮之外的其它几个“添加型部件”按钮的IsChecked属性。
        /// </summary>
        /// <param name="exButton">不清除此按钮的状态。</param>
        public void UnCheckInsertLineWidgetToggleButtons(RibbonToggleButton exButton)
        {
            RTBtnInsertBezierLine.IsChecked = false;
            RTBtnInsertBracketLine.IsChecked = false;
            RTBtnInsertEllipseLine.IsChecked = false;
            RTBtnInsertPolyLine.IsChecked = false;
            RTBtnInsertStraitLine.IsChecked = false;
            RTBtnInsertRectangleLine.IsChecked = false;
            RTBtnInsertRhombLine.IsChecked = false;
            RTBtnInsertTriangleLine.IsChecked = false;

            if (exButton != null)
            {
                exButton.IsChecked = true;
            }
        }

        private void RTBtnInsertLineWidget_Click(object sender, RoutedEventArgs e)
        {
            editorManager.FormatBrush = null;

            bool isCtrl = false;
            KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
            KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);
            if ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0)
            {
                isCtrl = true;
            }

            RibbonToggleButton rtBtn = sender as RibbonToggleButton;
            if (rtBtn == null) return;

            if (rtBtn.IsChecked != true)
            {
                editorManager.MouseDraggingType = Enums.PageDraggingType.None;
                return;
            }

            UnCheckInsertLineWidgetToggleButtons(rtBtn);

            string tagText = rtBtn.Tag as string;
            if (tagText == null) return;

            PrepareToInsertLineWidget(tagText, isCtrl);
        }

        private void RTBtnInsertLineWidget_DoubleClick(object sender, RoutedEventArgs e)
        {
            editorManager.FormatBrush = null;

            RibbonToggleButton rtBtn = sender as RibbonToggleButton;
            if (rtBtn == null) return;

            rtBtn.IsChecked = true;

            string tagText = rtBtn.Tag as string;
            if (tagText == null) return;

            PrepareToInsertLineWidget(tagText, true);
            e.Handled = true;
        }

        internal void PrepareToInsertLineWidget(string tagText, bool isCtrl)
        {
            switch (tagText)
            {
                case "F2":
                case "InsertStraitLine":
                    {
                        editorManager.MouseDraggingType = Enums.PageDraggingType.InsertStraitLine;
                        UnCheckInsertLineWidgetToggleButtons(RTBtnInsertStraitLine);
                        break;
                    }
                case "F3":
                case "InsertBezierLine":
                    {
                        editorManager.MouseDraggingType = Enums.PageDraggingType.InsertBezierLine;
                        UnCheckInsertLineWidgetToggleButtons(RTBtnInsertBezierLine);
                        break;
                    }
                case "F4":
                case "InsertPolyLine":
                    {
                        editorManager.MouseDraggingType = Enums.PageDraggingType.InsertPolyLine;
                        UnCheckInsertLineWidgetToggleButtons(RTBtnInsertPolyLine);
                        break;
                    }
                case "F5":
                case "InsertEllipseLine":
                    {
                        editorManager.MouseDraggingType = Enums.PageDraggingType.InsertEllipse;
                        UnCheckInsertLineWidgetToggleButtons(RTBtnInsertEllipseLine);
                        break;
                    }
                case "F6":
                case "InsertRectangleLine":
                    {
                        editorManager.MouseDraggingType = Enums.PageDraggingType.InsertRectangle;
                        UnCheckInsertLineWidgetToggleButtons(RTBtnInsertRectangleLine);
                        break;
                    }
                case "F7":
                case "InsertRhombLine":
                    {
                        editorManager.MouseDraggingType = Enums.PageDraggingType.InsertRhomb;
                        UnCheckInsertLineWidgetToggleButtons(RTBtnInsertRhombLine);
                        break;
                    }
                case "F8":
                case "InsertTriangleLine":
                    {
                        editorManager.MouseDraggingType = Enums.PageDraggingType.InsertTriangle;
                        UnCheckInsertLineWidgetToggleButtons(RTBtnInsertTriangleLine);
                        break;
                    }
                case "F9":
                case "InsertBracketLine":
                    {
                        editorManager.MouseDraggingType = Enums.PageDraggingType.InsertBracket;
                        UnCheckInsertLineWidgetToggleButtons(RTBtnInsertBracketLine);
                        break;
                    }
                //case "F10"://Ribbon自用
                default:
                    {
                        editorManager.ContinueInsertWidget = false;//如果都不支持，直接返回。
                        return;
                    }
            }

            editorManager.ContinueInsertWidget = isCtrl;
        }

        private void RMiLineWidth_Click(object sender, RoutedEventArgs e)
        {
            double newWidth = double.Parse((sender as RibbonMenuItem).Tag as string);

            Commands.SetWidgetLineWidthCommand.Execute(newWidth);
        }

        private void RMiLineArrows_Click(object sender, RoutedEventArgs e)
        {
            Enums.ArrowType newArrowType = (Enums.ArrowType)Enum.Parse(typeof(Enums.ArrowType),
                (sender as RibbonMenuItem).Tag as string);

            Commands.SetLineWidgetArrowsCommand.Execute(newArrowType);
        }

        private void RMiWidgetOpacity_Click(object sender, RoutedEventArgs e)
        {
            double newOpacity = double.Parse((sender as RibbonMenuItem).Tag as string);

            Commands.SetWidgetOpacityCommand.Execute(newOpacity);
        }

        private void RibbonMenuItem_RMILineDashType_Click(object sender, RoutedEventArgs e)
        {
            LineDashType.DashType newLineDashType = (LineDashType.DashType)Enum.Parse(typeof(LineDashType.DashType),
                (sender as RibbonMenuItem).Tag as string);

            Commands.SetWidgetLineDashTypeCommand.Execute(newLineDashType);
        }

        private void RMiPaddingWidth_Click(object sender, RoutedEventArgs e)
        {
            Thickness newthick = (Thickness)Globals.ThickConverter.ConvertFromString((sender as RibbonMenuItem).Tag as string);

            Commands.SetWidgetPaddingWidthCommand.Execute(newthick);
        }

        private void RRBtnTextOptionsIdeal_Click(object sender, RoutedEventArgs e)
        {
            TextOptions.SetTextFormattingMode(MainScrollViewer, TextFormattingMode.Ideal);
        }

        private void RRBtnTextOptionsDisplay_Click(object sender, RoutedEventArgs e)
        {
            TextOptions.SetTextFormattingMode(MainScrollViewer, TextFormattingMode.Display);
        }

        private void RRbtnDocumentDirectionHorizontal_Click(object sender, RoutedEventArgs e)
        {
            editorManager.Direction = Orientation.Horizontal;

            //if (editorManager.Children.Count <= 1)
            //{
            //    MessageBox.Show("　　此功能是用于临时指定多个页面存在时的排列方式，现在只有不多于一个页面，看不出效果！",
            //        Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            //}
        }

        private void RRbtnDocumentDirectionVertical_Click(object sender, RoutedEventArgs e)
        {
            editorManager.Direction = Orientation.Vertical;

            //if (editorManager.Children.Count <= 1)
            //{
            //    MessageBox.Show("　　此功能是用于临时指定多个页面存在时的排列方式，现在只有不多于一个页面，看不出效果！",
            //        Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            //}
        }

        private void RibbonWindow_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            bool isShift = false;
            KeyStates ksLeftShift = Keyboard.GetKeyStates(Key.LeftShift);
            KeyStates ksRightShift = Keyboard.GetKeyStates(Key.RightShift);
            if ((ksLeftShift & KeyStates.Down) > 0 || (ksRightShift & KeyStates.Down) > 0) isShift = true;

            bool isCtrl = false;
            KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
            KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);
            if ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0) isCtrl = true;

            bool isAlt = false;
            KeyStates ksLeftAlt = Keyboard.GetKeyStates(Key.LeftAlt);
            KeyStates ksRightAlt = Keyboard.GetKeyStates(Key.RightAlt);
            if ((ksLeftAlt & KeyStates.Down) > 0 || (ksRightAlt & KeyStates.Down) > 0) isAlt = true;


            switch (e.Key)
            {
                case Key.PageDown:
                    {
                        if (isCtrl && !isShift && !isAlt)
                        {
                            RTBtnStartPresentationByPath_Click(sender, e);
                            e.Handled = true;
                        }
                        break;
                    }
                case Key.PageUp:
                    {
                        if (isPresentatingByPath)
                        {
                            if (isCtrl && !isShift && !isAlt)
                            {
                                RTBtnEndPresentationByPath_Click(sender, e);
                                e.Handled = true;
                            }
                        }
                        break;
                    }
                case Key.Escape:
                    {
                        if (isPresentatingByPath)
                        {
                            if (isCtrl == false && !isShift && !isAlt)
                            {
                                RTBtnEndPresentationByPath_Click(sender, e);
                                e.Handled = true;
                            }
                        }
                        break;
                    }
                case Key.F1:
                    {
                        if (isCtrl == false)
                        {
                            if (isShift == false)
                            {
                                if (isAlt == false)
                                {
                                    ShowHelpFile();
                                }
                            }
                            else
                            {
                                if (isAlt == false)
                                {
                                    //Shift+F1
                                    Commands.SetWidgetFillBlankModeOnCommand.SetAllWidgetsInMainSelectedPageFillBlankModeOn();
                                }
                            }
                        }
                        else
                        {
                            //Ctrl+F1由自定义命令定义
                            if (isShift)
                            {
                                if (isAlt == false)
                                {
                                    //Ctrl+Shift+F1
                                    Commands.SetWidgetFillBlankModeOnCommand.SetWidgetsInWholeDocumentFillBlankModeOn();
                                }
                            }
                        }
                        break;
                    }
                case Key.F2:
                    {
                        if (isCtrl == false)
                        {
                            if (isShift)
                            {
                                if (isAlt == false)
                                {
                                    //Shift+F2
                                    Commands.SetWidgetFillBlankModeOffCommand.SetAllWidgetsInMainSelectedPageFillBlankModeOff();
                                }
                            }
                        }
                        else
                        {
                            //Ctrl+F2由自定义命令定义
                            if (isShift)
                            {
                                if (isAlt == false)
                                {
                                    //Ctrl+Shift+F2
                                    Commands.SetWidgetFillBlankModeOffCommand.SetWidgetsInWholeDocumentFillBlankModeOff();
                                }
                            }
                        }
                        break;
                    }
                case Key.F3:
                    {
                        if (isCtrl == false)
                        {
                            if (isShift)
                            {
                                if (isAlt == false)
                                {
                                    //Shift+F3
                                    Commands.SetWidgetTextVisibleOnCommand.SetAllWidgetsInMainSelectedPageTextVisibleOn();
                                }
                            }
                        }
                        else
                        {
                            //Ctrl+F3由自定义命令定义
                            if (isShift)
                            {
                                if (isAlt == false)
                                {
                                    //Ctrl+Shift+F3
                                    Commands.SetWidgetTextVisibleOnCommand.SetAllWidgetsInWholeDocumentTextVisibleOn();
                                }
                            }
                        }
                        break;
                    }
                case Key.F4:
                    {
                        if (isCtrl == false)
                        {
                            if (isShift)
                            {
                                if (isAlt == false)
                                {
                                    //Shift+F4
                                    Commands.SetWidgetTextVisibleOffCommand.SetAllWidgetsInMainSelectedPageTextVisibleOff();
                                }
                            }
                        }
                        else
                        {
                            //Ctrl+F4由自定义命令定义
                            if (isShift)
                            {
                                if (isAlt == false)
                                {
                                    //Ctrl+Shift+F4
                                    Commands.SetWidgetTextVisibleOffCommand.SetAllWidgetsInWholeDocumentTextVisibleOff();
                                }
                            }
                        }
                        break;
                    }
                case Key.Q:
                    {
                        if (isCtrl && isShift)
                        {
                            SearchPresentationAreasAndShowResult(string.Empty);
                            e.Handled = true;
                        }
                        break;
                    }
                case Key.F12:
                    {
                        if (isAlt == false && isShift == false)
                        {
                            if (isCtrl)
                            {
                                ImgShowLeftTools_MouseLeftButtonDown(null, null);
                            }
                            else
                            {
                                ImgShowRightTools_MouseLeftButtonDown(null, null);
                            }
                        }
                        e.Handled = true;
                        break;
                    }
                case Key.F11:
                    {
                        if (isAlt == false && isShift == false && isCtrl == false)
                        {
                            if (RTBtnMinimizeRibbon.IsChecked == true)
                            {
                                RTBtnMinimizeRibbon.IsChecked = false;
                            }
                            else
                            {
                                RTBtnMinimizeRibbon.IsChecked = true;
                            }
                        }
                        break;
                    }
            }
        }

        public void SearchPresentationAreasAndShowResult(string keyWord)
        {
            if (GLTools.Width.Value <= 20)
            {
                ImgShowLeftTools_MouseLeftButtonDown(null, null);
            }

            TCLeftTools.SelectedIndex = 2;

            SearchPresentationAreas(keyWord);
        }

        /// <summary>
        /// 快捷键主要分三块：
        /// 　　①由自定义命令管理的快捷键；
        /// 　　②某些特殊快捷键（单键字母键、Shift+字母键）由此事件处理器管理；
        /// 　　③某些快捷键需要屏蔽掉ScrollViewer自带的快捷键，
        /// 　　  必须由ScrollViewer的外层处理（本程序中放在窗口的PreviewKeyDown事件中处理。
        /// 
        /// Enter必须放在KeyDown中处理，否则会造成“怎么都关闭不了编辑窗口”的问题。
        /// </summary>
        private void MainScrollViewer_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            bool isAlt = false;
            KeyStates ksLeftAlt = Keyboard.GetKeyStates(Key.LeftAlt);
            KeyStates ksRightAlt = Keyboard.GetKeyStates(Key.RightAlt);

            if ((ksLeftAlt & KeyStates.Down) > 0 || (ksRightAlt & KeyStates.Down) > 0) isAlt = true;

            bool isCtrl = false;
            KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
            KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);

            if ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0) isCtrl = true;

            bool isShift = false;
            KeyStates ksLeftShift = Keyboard.GetKeyStates(Key.LeftShift);
            KeyStates ksRightShift = Keyboard.GetKeyStates(Key.RightShift);

            if ((ksLeftShift & KeyStates.Down) > 0 || (ksRightShift & KeyStates.Down) > 0) isShift = true;

            switch (e.Key)
            {
                case Key.Enter:
                    {
                        if (isAlt == false)
                        {
                            if (isShift)
                            {
                                if (isCtrl == false)
                                {
                                    LunarMessage.Warning(Commands.InsertSimilarWidgetAndEditCommand.Execute(0));
                                }
                            }
                            else
                            {
                                if (isCtrl == false)
                                {
                                    LunarMessage.Warning(Commands.EditCommand.Execute());
                                }
                                else
                                {
                                    LunarMessage.Warning(Commands.InsertSimilarWidgetAndEditCommand.Execute(editorManager.DefaultFontSize * 2, true));
                                }
                            }

                            e.Handled = true;
                        }
                        break;
                    }
                case Key.F2:
                    {
                        if (isCtrl == false && isAlt == false && isShift == false)
                        {
                            PrepareToInsertLineWidget("F2", isCtrl);
                        }
                        break;
                    }
                case Key.F3:
                    {
                        if (isCtrl == false && isAlt == false && isShift == false)
                        {
                            PrepareToInsertLineWidget("F3", isCtrl);
                        }
                        break;
                    }
                case Key.F4:
                    {
                        if (isCtrl == false && isAlt == false && isShift == false)
                        {
                            PrepareToInsertLineWidget("F4", isCtrl);
                        }
                        break;
                    }
                case Key.F5:
                    {
                        if (isCtrl == false && isAlt == false && isShift == false)
                        {
                            PrepareToInsertLineWidget("F5", isCtrl);
                        }
                        break;
                    }
                case Key.F6:
                    {
                        if (isCtrl == false && isAlt == false && isShift == false)
                        {
                            PrepareToInsertLineWidget("F6", isCtrl);
                        }
                        break;
                    }
                case Key.F7:
                    {
                        if (isCtrl == false && isAlt == false && isShift == false)
                        {
                            PrepareToInsertLineWidget("F7", isCtrl);
                        }
                        break;
                    }
                case Key.F8:
                    {
                        if (isCtrl == false && isAlt == false && isShift == false)
                        {
                            PrepareToInsertLineWidget("F8", isCtrl);
                        }
                        break;
                    }
                case Key.F9:
                    {
                        if (isCtrl == false && isAlt == false && isShift == false)
                        {
                            PrepareToInsertLineWidget("F9", isCtrl);
                        }
                        break;
                    }
                case Key.OemMinus:
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isShift && isAlt == false)//Shift+_插入水平线
                            {
                                LunarMessage.Warning(Commands.InsertHorizontalLineCommand.Execute());
                            }
                        }
                        break;
                    }
                case Key.E:
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isShift && isAlt == false)//垂直居中对齐
                            {
                                LunarMessage.Warning(Commands.AlignWidgetsToVerticalCenterCommand.Execute());
                            }
                        }
                        break;
                    }
                case Key.H:
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isAlt == false)
                            {
                                if (isShift)//等宽
                                {
                                    LunarMessage.Warning(Commands.SameSizeVerticalCommand.Execute());
                                }
                                else
                                {
                                    LunarMessage.Warning(Commands.AlignListHorizontalCommand.Execute());//自动排列成间距10。
                                }
                            }
                        }
                        break;
                    }
                case Key.W://向上选定部件
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isAlt == false)
                            {
                                if (isShift)//等高
                                {
                                    LunarMessage.Warning(Commands.SameSizeHorizontalCommand.Execute());
                                }
                                else
                                {
                                    LunarMessage.Warning(Commands.SelectAtUpCommand.Execute());
                                }
                            }
                        }
                        break;
                    }
                case Key.A://向左选定部件
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isAlt == false)
                            {
                                if (isShift == false)
                                {
                                    LunarMessage.Warning(Commands.SelectAtLeftCommand.Execute());
                                }
                            }
                        }
                        break;
                    }
                case Key.P:
                    {
                        // Ctrl+Shift+P，由UICommand定义，功能是“插入新页”
                        // Ctrl+Alt+P，由UICommand定义，功能是“复制页”
                        if (isCtrl)
                        {
                            if (isShift == false)
                            {
                                if (isAlt == false)
                                {
                                    PrintSelectedPagesAsA4();//Ctrl+P打印选定页面。
                                }
                            }
                        }
                        else
                        {
                            if (isCtrl == false)
                            {
                                if (isShift == false)
                                {
                                    if (isAlt == false)
                                    {
                                        LunarMessage.Warning(Commands.InsertPictureBoxCommand.Execute());//P
                                    }
                                }
                            }
                        }
                        break;
                    }
                case Key.S://向下选定部件
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isCtrl == false)
                            {
                                if (isShift == false)
                                {
                                    LunarMessage.Warning(Commands.SelectAtDownCommand.Execute());
                                }
                            }
                        }
                        break;
                    }
                case Key.D://向右选定部件
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isAlt == false)
                            {
                                if (isShift == false)
                                {
                                    LunarMessage.Warning(Commands.SelectAtRightCommand.Execute());
                                }
                            }
                        }
                        break;
                    }
                case Key.J:
                    {
                        if (isCtrl)
                        {
                            if (isShift && isAlt == false)
                            {
                                LunarMessage.Warning(Commands.QuickCopiesCommand.Execute("Left"));
                            }
                        }
                        else
                        {
                            if (isAlt == false)
                            {
                                if (isShift)
                                {
                                    LunarMessage.Warning(Commands.InsertSimilarWidgetAtCommand.Execute(Key.Left));
                                }
                                else
                                {
                                    LunarMessage.Warning(Commands.InsertSimilarWidgetAndEditCommand.Execute(-editorManager.DefaultFontSize * 2)); //左缩进
                                }
                            }
                        }
                        break;
                    }
                case Key.L:
                    {
                        if (isCtrl)
                        {
                            if (isShift && isAlt == false)
                            {
                                LunarMessage.Warning(Commands.QuickCopiesCommand.Execute("Right"));
                            }
                        }
                        else
                        {
                            if (isAlt == false)
                            {
                                if (isShift)
                                {
                                    LunarMessage.Warning(Commands.InsertSimilarWidgetAtCommand.Execute(Key.Right));
                                }
                                else
                                {
                                    LunarMessage.Warning(Commands.InsertSimilarWidgetAndEditCommand.Execute(editorManager.DefaultFontSize * 2)); //右缩进
                                }
                            }
                        }
                        break;
                    }
                case Key.K:
                    {
                        if (isCtrl)
                        {
                            if (isShift && isAlt == false)
                            {
                                LunarMessage.Warning(Commands.QuickCopiesCommand.Execute("Bottom"));
                            }
                        }
                        else
                        {
                            if (isAlt == false)
                            {
                                //无论有无Shift，K的行为是一样的。但没有Shift时会直接进入编辑状态。
                                if (isShift)
                                {
                                    LunarMessage.Warning(Commands.InsertSimilarWidgetAtCommand.Execute(Key.Down));
                                }
                                else
                                {
                                    LunarMessage.Warning(Commands.InsertSimilarWidgetAndEditCommand.Execute(0));
                                }
                            }
                        }
                        break;
                    }
                case Key.I://JKLI四向插入文本块或矩形，但不提供向上
                    {
                        if (isCtrl)
                        {
                            if (isShift && isAlt == false)
                            {
                                LunarMessage.Warning(Commands.QuickCopiesCommand.Execute("Top"));
                            }
                        }
                        else
                        {
                            if (isShift && isAlt == false)
                            {
                                LunarMessage.Warning(Commands.InsertSimilarWidgetAtCommand.Execute(Key.Up));
                            }
                        }
                        break;
                    }
                case Key.Z:
                    {

                        if (isCtrl == false && isAlt == false)
                        {
                            if (isShift)
                            {
                                LunarMessage.Warning(Commands.InsertSimilarWidgetAndEditCommand.Execute(editorManager.DefaultFontSize * 2, true, true, true));
                            }
                            else
                            {
                                LunarMessage.Warning(Commands.InsertSimilarWidgetAndEditCommand.Execute(editorManager.DefaultFontSize * 2, true, true, false));
                            }
                        }
                        break;
                    }
                case Key.T:
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isAlt == false)
                            {
                                if (isShift == false)
                                {
                                    LunarMessage.Warning(Commands.AlignListVerticalCommand.Execute(10, true, true));//自动格式化矩形，且排列为左对齐的列表样式。                                    
                                }
                                else
                                {
                                    LunarMessage.Warning(Commands.FoamatAsTableCommand.Execute(10, true));//尝试按“表格”的样式格式化选定的各部件（最好是矩形）。
                                }
                            }
                        }
                        break;
                    }
                case Key.V:
                    {
                        if (isCtrl)
                        {
                            //Ctrl+V粘贴由自定义命令定义，不在此处。
                        }
                        else
                        {
                            if (isAlt == false)
                            {
                                if (isShift == false)
                                {
                                    LunarMessage.Warning(Commands.AlignListVerticalCommand.Execute());//自动排列成间距10。
                                }
                                else
                                {
                                    LunarMessage.Warning(Commands.AlignListVerticalCommand.Execute(null, true, true, true));//自动排列成间距10。
                                }
                            }
                        }
                        break;
                    }
                //case Key.OemTilde://波形符键
                case Key.C://Command
                case Key.Space:
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isAlt == false && isShift == false)
                            {
                                CbxQuickCommandBox.Focus();
                                e.Handled = true;
                            }
                        }
                        break;
                    }
                case Key.Back:
                    {
                        if (isCtrl)
                        {

                        }
                        else
                        {
                            if (isShift && isAlt == false)
                            {
                                CbxQuickCommandBox.Focus();
                                e.Handled = true;
                            }
                        }
                        break;
                    }
                case Key.D1://添加或格式化为一、级标题矩形
                    {
                        if (isAlt == false)
                        {
                            if (isShift == false)
                            {
                                if (isCtrl)
                                {
                                    string result = Commands.InsertTextAreaAsTitleCommand.Execute(Enums.TitleStyle.T1);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　未能插入标题文本块，错误信息如下：\r\n" + result,
                                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                            else
                            {
                                if (!isCtrl)
                                {
                                    string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T1);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n　　" + result, Globals.AppName,
                                            MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                        }
                        return;
                    }
                case Key.D2://添加或格式化为（二）级标题矩形
                    {
                        if (isAlt == false)
                        {
                            if (isShift == false)
                            {
                                if (isCtrl)
                                {
                                    string result = Commands.InsertTextAreaAsTitleCommand.Execute(Enums.TitleStyle.T2);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　未能插入标题文本块，错误信息如下：\r\n" + result,
                                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                            else
                            {
                                if (!isCtrl)
                                {
                                    string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T2);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n　　" + result, Globals.AppName,
                                            MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                        }
                        return;
                    }
                case Key.D3://添加或格式化为３.级标题矩形
                    {
                        if (isAlt == false)
                        {
                            if (isShift == false)
                            {
                                if (isCtrl)
                                {
                                    string result = Commands.InsertTextAreaAsTitleCommand.Execute(Enums.TitleStyle.T3);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　未能插入标题文本块，错误信息如下：\r\n" + result,
                                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                            else
                            {
                                if (!isCtrl)
                                {
                                    string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T3);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n　　" + result, Globals.AppName,
                                            MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                        }
                        return;
                    }
                case Key.D4://添加或格式化为（４）级标题矩形
                    {
                        if (isAlt == false)
                        {
                            if (isShift == false)
                            {
                                if (isCtrl)
                                {
                                    string result = Commands.InsertTextAreaAsTitleCommand.Execute(Enums.TitleStyle.T4);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　未能插入标题文本块，错误信息如下：\r\n" + result,
                                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                            else
                            {
                                if (!isCtrl)
                                {
                                    string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T4);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n　　" + result, Globals.AppName,
                                            MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                        }
                        return;
                    }
                case Key.D5://添加或格式化为正文级标题矩形
                    {
                        if (isAlt == false)
                        {
                            if (isShift == false)
                            {
                                if (isCtrl)
                                {
                                    string result = Commands.InsertTextAreaAsTitleCommand.Execute(Enums.TitleStyle.T5);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　未能插入标题文本块，错误信息如下：\r\n" + result,
                                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                            else
                            {
                                if (!isCtrl)
                                {
                                    string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T5);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n　　" + result, Globals.AppName,
                                            MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                        }
                        return;
                    }
                case Key.D6:
                    {
                        if (isAlt == false)
                        {
                            if (isShift == false)
                            {
                                if (isCtrl)
                                {
                                    string result;

                                    PageEditor mainSelPage = editorManager.GetMainSelectedPageEditor();
                                    if (mainSelPage == null)
                                    {
                                        result = Commands.InsertTextAreaAsTitleCommand.Execute(Enums.TitleStyle.Normal, null, 1);
                                    }
                                    else
                                    {
                                        Widget mainSelWidget = mainSelPage.GetMainSelectedWidget();
                                        if (mainSelWidget == null)// || mainSelWidget is Widgets.TextArea == false)
                                        {
                                            result = Commands.InsertTextAreaAsTitleCommand.Execute(Enums.TitleStyle.Normal, null, 0);
                                        }
                                        else
                                        {
                                            result = Commands.InsertTextAreaAsTitleCommand.Execute(Enums.TitleStyle.Normal, mainSelWidget.TitleLevel, 0);
                                        }
                                    }

                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　未能插入标题矩形，错误信息如下：\r\n" + result,
                                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                            else
                            {
                                if (!isCtrl)
                                {
                                    string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.Normal);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n　　" + result, Globals.AppName,
                                            MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                        }
                        return;
                    }
                case Key.D0://添加顶级标题矩形框
                    {
                        if (isAlt == false)
                        {
                            if (isShift == false)
                            {
                                if (isCtrl)
                                {
                                    string result = Commands.InsertTextAreaAsTitleCommand.Execute(Enums.TitleStyle.MainTitle);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　未能插入标题文本块，错误信息如下：\r\n" + result,
                                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                            else
                            {
                                if (!isCtrl)
                                {
                                    string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.MainTitle);
                                    if (result != string.Empty)
                                    {
                                        MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n　　" + result, Globals.AppName,
                                            MessageBoxButton.OK, MessageBoxImage.Warning);
                                    }
                                }
                            }
                        }
                        return;
                    }
                case Key.U:
                    {
                        if (isAlt == false)
                        {
                            if (!isShift && !isCtrl)
                            {
                                Widgets.Widget mainSelWidget = editorManager.GetMainSelectedWidget();
                                if (mainSelWidget != null)
                                {
                                    Widgets.TextArea tw = mainSelWidget as Widgets.TextArea;
                                    if (tw != null)
                                    {
                                        if (tw.TitleLevel > Enums.TitleStyle.MainTitle)
                                        {
                                            string result = Commands.FormatTitleCommand.FormatTitle(tw.TitleLevel - 1);
                                            if (result != string.Empty)
                                            {
                                                MessageBox.Show("　　移动标题层级出错。异常信息如下：\r\n　　" + result, Globals.AppName,
                                                    MessageBoxButton.OK, MessageBoxImage.Warning);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    }
                case Key.O:
                    {
                        if (isAlt == false)
                        {
                            if (!isShift && !isCtrl)
                            {
                                Widgets.Widget mainSelWidget = editorManager.GetMainSelectedWidget();
                                if (mainSelWidget != null)
                                {
                                    Widgets.TextArea tw = mainSelWidget as Widgets.TextArea;
                                    if (tw != null)
                                    {
                                        if (tw.TitleLevel < Enums.TitleStyle.Normal)
                                        {
                                            string result = Commands.FormatTitleCommand.FormatTitle(tw.TitleLevel + 1);
                                            if (result != string.Empty)
                                            {
                                                MessageBox.Show("　　移动标题层级出错。异常信息如下：\r\n　　" + result, Globals.AppName,
                                                    MessageBoxButton.OK, MessageBoxImage.Warning);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    }
                case Key.OemComma://逗号键
                    {
                        if (isShift && isAlt == false && isCtrl == false)
                        {
                            //标题层级变小（这样看起来字号变大，与Word操作体验更接近）

                            FormatTitleCommand.FormatTitle(Enums.TitleStyle.Normal, false);
                        }
                        break;
                    }
                case Key.OemPeriod://句号键，句点键
                    {
                        if (isShift && isAlt == false && isCtrl == false)
                        {
                            //标题层级变大（这样看起来字号变大，与Word操作体验更接近）

                            FormatTitleCommand.FormatTitle(Enums.TitleStyle.Normal, true);
                        }
                        break;
                    }
            }
        }

        private void MainScrollViewer_KeyUp(object sender, KeyEventArgs e)
        {
            //否则会导致组合快捷键（例如Ctrl+Alt+P）误弹出快捷菜单。
            if (e.SystemKey != Key.None && e.SystemKey != Key.F10)
            {
                return;
            }

            //弹出右键菜单
            switch (e.Key)
            {
                //不能用RightCtrl，否则行为诡异得很。
                case Key.Apps:
                    {
                        OpenContextMenu();
                        e.Handled = true;//否则当KeyUp事件触发时，会立即将刚刚弹出的快捷菜单再隐藏掉。
                        break;
                    }
                case Key.System:
                    {
                        //Shift+F10或Alt+Shift，系统自带，可用于代替Key.Apps。
                        //但Key.System行为与Key.Apps不同（Key.Apps第二次按下会隐藏快捷菜单，但Key.System则是再显示一遍）。
                        OpenContextMenu();
                        e.Handled = true;//否则当KeyUp事件触发时，会立即将刚刚弹出的快捷菜单再隐藏掉。
                        break;
                    }
            }
        }

        /// <summary>
        /// 弹出右键菜单。
        /// </summary>
        private void OpenContextMenu()
        {

            if (editorManager != null)
            {
                Widgets.Widget mainSelWidget = editorManager.GetMainSelectedWidget();
                if (mainSelWidget != null && mainSelWidget.ContextMenu != null)
                {
                    mainSelWidget.ContextMenu.IsOpen = true;
                }
                else
                {
                    PageEditor mainSelPage = editorManager.GetMainSelectedPageEditor();
                    if (mainSelPage != null)
                    {
                        mainSelPage.ContextMenu.IsOpen = true;
                    }
                }
            }
        }

        /// <summary>
        /// 在数据库中查找符合条件的记录。
        /// </summary>
        /// <param name="keyword">如果为null，才会根据主界面上关键词输入框的文本查找。
        /// 如果不是，直接按指定的关键词查找。</param>
        /// <returns>如果正常执行，返回string.Empty。否则返回错误消息。</returns>
        internal string SearchInDatabase(string outKeywork = null)
        {
            string keyWord;
            if (outKeywork == null)
            {
                keyWord = TbxSearchInDatabase.Text;
            }
            else
            {
                keyWord = outKeywork;

                if (keyWord.Length <= 0) return "　　用于查找的关键词不能为空，也不能全是空格。";
            }

            DataTable table = Globals.GlobalDataSetIn.Tables["WidgetsSet"];
            table.Clear();

            string sqlWhereSubSentence = "";
            sqlWhereSubSentence = "(((WidgetsSet.Title) Like \"%" + keyWord + "%\")"
                            + " OR ((WidgetsSet.InnerText) Like \"%" + keyWord + "%\")"
                            + " OR ((WidgetsSet.Description) Like \"%" + keyWord + "%\")"
                           + " OR ((WidgetsSet.Comment) Like \"%" + keyWord + "%\"))";

            //★★注意：在Access中通配符用“*”，而在Access的数据提供者中写SQL语句时，用“&”。

            OleDbDataAdapter oda = new OleDbDataAdapter("SELECT * FROM WidgetsSet WHERE " +
                    sqlWhereSubSentence + " ORDER BY ID",
                    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"" + Globals.PathOfDataBase + "\"");
            try
            {
                oda.Fill(table);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            finally
            {
                oda.Dispose();
            }

            return string.Empty;
        }

        private void TbxSearchInDatabase_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && TbxSearchInDatabase.IsFocused)
            {
                SearchInDatabase();
                e.Handled = true;//避免误调用Command.Edit.Execute()这个自定义命令的方法。
            }
        }

        private void BtnSearchInDatabase_Click(object sender, RoutedEventArgs e)
        {
            SearchInDatabase();
        }

        private void MainScrollViewer_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            MainScrollViewer.Focus();
            //否则当焦点移动到搜索框中后，再选定部件，上、下、左、右快捷键不起作用。
        }

        private void RibbonWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //在注册表中注册程序路径
            //RegistryKey hklm = Registry.LocalMachine;
            //RegistryKey software = hklm.OpenSubKey("SOFTWARE", true);
            //RegistryKey installedPathKey = software.CreateSubKey("Lunar Concept");
            //installedPathKey.SetValue("InstalledPath", Globals.FullPathOfApp);

            //载入自定义鼠标指针。
            System.Windows.Resources.StreamResourceInfo sri = Application.GetResourceStream(
                new Uri("./Resources/GridSplliter.cur", UriKind.Relative));
            Cursor c = new Cursor(sri.Stream);
            GSLeftTools.Cursor = GSRightTools.Cursor = c;

            //看有没有传入命令行参数。
            if (Globals.CmdParameterString != null)
            {
                //这个命令的调用，不能放在窗口载入之前。
                //否则，因为窗口布局尚未完成，文档载入时创建的“组部件”的尺寸会出问题。
                LunarMessage.Warning(Commands.OpenDocumentCommand.Execute(Globals.CmdParameterString));

                //即使以命令行方式指定了要在程序启动时打开的文档，在打开此文档后，还需要进行其它初始化。
            }

            MainScrollViewer.Focus();//避免命令输入框获取焦点。

            Rect bounds = Properties.Settings.Default.StartWindowLocationSetting;

            if (bounds != null && (bounds.Left != 0 || bounds.Top != 0))
            {
                if (bounds.Width == 0) bounds.Width = 800;
                if (bounds.Height == 0) bounds.Height = 560;

                this.Top = bounds.Top;
                this.Left = bounds.Left;

                // Restore the size only for a manually sized thisdow.
                if (this.SizeToContent == SizeToContent.Manual)
                {
                    this.Width = bounds.Width;
                    this.Height = bounds.Height;
                }

                if (MainScrollViewer.ViewportWidth == MainScrollViewer.ActualWidth)
                {
                    GRTools.Width = new GridLength(300);//滚动条未显示，说明宽度足够，载入时显示右工具栏。
                }
                else
                {
                    GRTools.Width = new GridLength(10);//显示滚动条，说明宽度不够，载入时不显示右工具栏。
                }
            }

            this.magnifierControlPanel = new Popup() { Placement = PlacementMode.Top, IsOpen = false };
            magnifierControlPanel.Child = new MagnifilerControlPanel(this.editorManager);

            Binding magnifierPopUpBinding = new Binding();
            magnifierPopUpBinding.Source = ImgShowMagnifier;

            magnifierControlPanel.SetBinding(Popup.PlacementTargetProperty, magnifierPopUpBinding);

            var outputImagesDirectoryPath = Globals.ConfigManager.Get("OutputImagesDirectoryPath");
            if (Directory.Exists(outputImagesDirectoryPath))
            {
                tbOutputImagesDirectoryPath.Text = outputImagesDirectoryPath;
            }

            // 载入用户保存的样式列表
            LoadUserStyles();

            // 默认关闭输入法
            Globals.SwitchInputMethod(false);
        }

        /// <summary>
        /// 命令输入窗口，执行命令。
        /// </summary>
        private void CbxQuickCommandBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                //执行命令

                MainScrollViewer.Focus();

                //如果去除空格之后啥都没有，直接返回，什么都不做。
                string tmp = CbxQuickCommandBox.Text;
                tmp = tmp.Replace("　", " "); tmp = tmp.Replace("_", " "); tmp = tmp.Replace("/", " ");
                tmp = tmp.Trim();
                if (tmp.Length <= 0) { MainScrollViewer.Focus(); CbxQuickCommandBox.Text = string.Empty; return; }

                string resultOfCommand = RunTextCommand.Run(CbxQuickCommandBox.Text);

                //如果执行成功，返回主界面，命令窗口失去焦点。
                //如果执行失败，显示错误消息。


                if (resultOfCommand != string.Empty)
                {
                    MessageBox.Show("　　命令执行失败！错误消息：\r\n\r\n　　" + resultOfCommand,
                        Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    CbxQuickCommandBox.Focus();
                    return;
                }


                //执行成功，将使用过的命令临时存储起来。
                CbxQuickCommandBox.Items.Insert(0, CbxQuickCommandBox.Text);
                CbxQuickCommandBox.Text = string.Empty;
            }
            else if (e.Key == Key.Escape)
            {
                MainScrollViewer.Focus();
            }
        }

        private void ListTextCommands()
        {
            Type[] _tcClasses = Globals.MainWindow.GetType().Module.FindTypes(Module.FilterTypeNameIgnoreCase, "_tc*");

            foreach (Type t in _tcClasses)
            {
                string[] texts = new string[3];
                TextCommandAttribute tna = (TextCommandAttribute)
                        Attribute.GetCustomAttribute(t, typeof(TextCommandAttribute));
                if (tna != null)
                {
                    texts[0] = "命令类别：" + tna.CommandType.ToString();
                    texts[1] = "命令文本：" + tna.AliasNames;
                    texts[2] = "命令描述：" + tna.Description;
                }

                TextCommandListItem tli = new TextCommandListItem(t.Name, texts);
                LBTextCommandsList.Items.Add(tli);
            }
        }

        private void BtnTextCommand_Click(object sender, RoutedEventArgs e)
        {
            Type[] _tcClasses = Globals.MainWindow.GetType().Module.FindTypes(Module.FilterTypeNameIgnoreCase, "_tc*");

            StringBuilder sb = new StringBuilder().Append("========\r\n");

            foreach (Type t in _tcClasses)
            {
                TextCommandAttribute tna = (TextCommandAttribute)
                        Attribute.GetCustomAttribute(t, typeof(TextCommandAttribute));
                if (tna != null)
                {
                    sb.Append(string.Format("　　命令类别：{0,-40}\r\n　　命令文本：{1,-40}\r\n　　命令描述：{2,-40}\r\n　　========\r\n",
                        tna.CommandType.ToString(), tna.AliasNames, tna.Description));
                }
            }

            try
            {
                Clipboard.SetData(DataFormats.UnicodeText, sb.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show("　　发生意外，未能向剪贴板写入文本！系统剪贴板可能被其它程序占用。" +
                    "异常信息如下：\r\n" +
                    ex.Message + "\r\n" + ex.StackTrace, Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            MessageBox.Show("　　已将命令列表复制到剪贴板中。", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Information);
        }

        private void MainScrollViewer_GotFocus(object sender, RoutedEventArgs e)
        {
            Globals.SwitchInputMethod(false);
        }

        private void CbxQuickCommandBox_GotFocus(object sender, RoutedEventArgs e)
        {
            CbxQuickCommandBox.Background = Brushes.White;
            CbxQuickCommandBox.Foreground = Brushes.Black;
            Globals.SwitchInputMethod(false);//命令一般用英文字母（即使汉语拼音也比汉字快些），快捷些。
        }

        private void CbxQuickCommandBox_LostFocus(object sender, RoutedEventArgs e)
        {
            CbxQuickCommandBox.Background = Globals.TextCommandInputBoxBackground;
            //CbxQuickCommandBox.Text = string.Empty;//不能用这个，会造成“历史命令”失效。
            CbxQuickCommandBox.Foreground = Brushes.Transparent;
        }

        private void RTBtnFormatBrush_Click(object sender, RoutedEventArgs e)
        {
            if (editorManager.FormatBrush != null)
            {
                editorManager.FormatBrush = null;//取消格式刷
                RTBtnFormatBrush.IsChecked = false;
            }
            else
            {
                //看能否取格式

                if (editorManager == null)
                {
                    MessageBox.Show("　　发生意外，未找到页面管理器！", Globals.AppName,
                        MessageBoxButton.OK, MessageBoxImage.Warning);
                    RTBtnFormatBrush.IsChecked = false;
                    return;
                }

                Widgets.Widget w = editorManager.GetMainSelectedWidget();
                if (w == null)
                {
                    MessageBox.Show("　　请先选定一个公式！", Globals.AppName,
                        MessageBoxButton.OK, MessageBoxImage.Warning);
                    RTBtnFormatBrush.IsChecked = false;
                    return;
                }

                KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
                KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);

                bool isCtrl = false;
                if ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0)
                {
                    isCtrl = true;
                }

                Widgets.ContentWidget cw = w as Widgets.ContentWidget;
                if (cw != null)
                {
                    editorManager.FormatBrush = new FormatBrush()
                    {
                        DefaultWidgetStyle = new WidgetStyle(cw.GetType().Name)
                        {
                            IsShadowVisible = cw.IsShadowVisible,
                            WidgetOpacity = cw.WidgetOpacity,
                            WidgetBackColor = cw.WidgetBackColor,
                            WidgetLineColor = cw.WidgetLineColor,
                            WidgetLineWidth = cw.WidgetLineWidth,
                            WidgetForeColor = cw.WidgetForeColor,
                            WidgetPadding = cw.WidgetPadding,
                            WidgetOutBorderType = cw.OuterBorderType,
                        },
                        OnlyFormatOnceTime = !isCtrl,
                        SourceWidgetType = cw.WidgetType,
                    };
                    return;
                }

                Widgets.ArrowLineWidget alw = w as Widgets.ArrowLineWidget;
                if (alw != null)
                {
                    editorManager.FormatBrush = new FormatBrush()
                    {
                        DefaultWidgetStyle = new WidgetStyle(alw.GetType().Name)
                        {
                            Arrows = alw.Arrows,
                            IsShadowVisible = alw.IsShadowVisible,
                            LineDash = alw.LineDash,
                            WidgetOpacity = alw.WidgetOpacity,
                            WidgetBackColor = alw.WidgetBackColor,
                            WidgetLineWidth = alw.WidgetLineWidth,
                            WidgetForeColor = alw.WidgetForeColor,
                            WidgetPadding = alw.WidgetPadding,
                            Radius = alw.Radius,
                        },
                        OnlyFormatOnceTime = !isCtrl,
                        SourceWidgetType = alw.WidgetType,
                    };
                    return;
                }

                Widgets.ShapeWidget sw = w as Widgets.ShapeWidget;
                if (sw != null)
                {
                    FormatBrush newFormatBrush = new FormatBrush()
                    {
                        OnlyFormatOnceTime = !isCtrl,
                        SourceWidgetType = sw.WidgetType,
                    };

                    newFormatBrush.DefaultWidgetStyle = new WidgetStyle(sw.GetType().Name)
                    {
                        IsShadowVisible = sw.IsShadowVisible,
                        LineDash = sw.LineDash,
                        WidgetOpacity = sw.WidgetOpacity,
                        WidgetBackColor = sw.WidgetBackColor,
                        WidgetLineColor = sw.WidgetLineColor,
                        WidgetLineWidth = sw.WidgetLineWidth,
                        WidgetForeColor = sw.WidgetForeColor,
                    };

                    Widgets.RectangleWidget rw = w as Widgets.RectangleWidget;//截止2012年8月20日，只有矩形部件支持圆角率这个属性。
                    if (rw != null)
                    {
                        newFormatBrush.DefaultWidgetStyle.Radius = rw.Radius;
                    }

                    Widgets.RhombWidget rw2 = w as Widgets.RhombWidget;
                    if (rw2 != null)
                    {
                        newFormatBrush.DefaultWidgetStyle.WidgetForm = rw2.WidgetForm;
                    }

                    Widgets.TriangleWidget tw = w as Widgets.TriangleWidget;
                    if (tw != null)
                    {
                        newFormatBrush.DefaultWidgetStyle.TriangleForm = tw.TriangleForm;
                    }

                    editorManager.FormatBrush = newFormatBrush;
                    return;
                }
            }
        }

        /// <summary>
        /// 尝试滚动编辑区来显示指定部件。
        /// </summary>
        /// <param name="widget">要显示的部件。</param>
        /// <param name="vOffset">指纵向底边要多保留的区域高。</param>
        internal string TryToShowWidgetInScrollViewer(Widgets.Widget widget, double vOffset = 0)
        {
            if (widget == null) return "　　指定的部件为null。";
            if (widget.MasterEditor == null) return "　　指定部件的MasterEditor为null。";
            if (widget.MasterEditor.MasterManager == null) return "　　指定部件的MasterEditor的MasterEditor为null。";
            if (widget.MasterEditor.MasterManager != this.editorManager) return "　　指定部件所在的页面管理器与当前页面管理器不一致。";

            double scrollBarWidth = MainScrollViewer.ActualWidth - MainScrollViewer.ViewportWidth;
            Rect rect = widget.RealRect;

            //如何求出当前部件相对于ScrollViewer的位置呢？
            Point pageTopLeftToEditorManager = widget.MasterEditor.TranslatePoint(new Point(0, 0), editorManager);
            Point widgetTopLeft = widget.TopLeft;
            Point widgetBottomRight = widget.BottomRight;

            Point widgetTopLeftToEditorManager = new Point(pageTopLeftToEditorManager.X + widgetTopLeft.X,
                pageTopLeftToEditorManager.Y + widgetTopLeft.Y);
            Point widgetBottomRightToEditorManager = new Point(
                widgetTopLeftToEditorManager.X + (widgetBottomRight.X - widgetTopLeft.X) + widget.MasterEditor.Margin.Left,
                widgetTopLeftToEditorManager.Y + (widgetBottomRight.Y - widgetTopLeft.Y) + widget.MasterEditor.Margin.Top);

            Rect widgetRectToEditorManager = new Rect(widgetTopLeftToEditorManager, widgetBottomRightToEditorManager);

            Point scrollViewerTopLeftToEditorManager = MainScrollViewer.TranslatePoint(new Point(0, 0), editorManager);

            //要防止ScrollViewer高、宽度过小时程序崩溃。
            double w = MainScrollViewer.ViewportWidth - editorManager.Margin.Left;
            double h = MainScrollViewer.ViewportHeight - editorManager.Margin.Top - vOffset;

            if (w <= 0 || h <= 0) return "　　当前窗口太小，无法自动定位到指定部件。";//ScrollViewer太小，直接返回。

            Rect scrollViewerRectToEditorManager = new Rect(scrollViewerTopLeftToEditorManager.X,
                scrollViewerTopLeftToEditorManager.Y, w, h);//vOffset一般用在“插入并编辑”操作中。

            if (scrollViewerRectToEditorManager.IntersectsWith(widgetRectToEditorManager))
            {
                return string.Empty;//两者相交，说明就在可视区，直接返回。
            }

            //如果宽度小于可视区宽度，则横向滚动，
            //如果高度小于可视区高度，则纵向滚动，
            //滚动时遵循靠近边原则。
            //如果已经在可视区，则不滚动。

            Rect sRect = scrollViewerRectToEditorManager;
            Rect wRect = widgetRectToEditorManager;

            if (wRect.Width < sRect.Width)
            {
                double oldHOffset = MainScrollViewer.HorizontalOffset;
                if (wRect.Left < sRect.Left)
                {
                    MainScrollViewer.ScrollToHorizontalOffset(oldHOffset - (sRect.Left - wRect.Left));
                }
                else if (wRect.Right > sRect.Right)
                {
                    MainScrollViewer.ScrollToHorizontalOffset(oldHOffset + (wRect.Right - sRect.Right) + scrollBarWidth);
                }
            }

            if (wRect.Height < sRect.Height)
            {
                double oldVOffset = MainScrollViewer.VerticalOffset;
                if (wRect.Top < sRect.Top)
                {
                    MainScrollViewer.ScrollToVerticalOffset(oldVOffset - (sRect.Top - wRect.Top));
                }
                else if (wRect.Bottom > sRect.Bottom)
                {
                    MainScrollViewer.ScrollToVerticalOffset(oldVOffset + (wRect.Bottom - sRect.Bottom) + scrollBarWidth);
                }
            }

            return string.Empty;
        }

        private void RMIPrintPagesAsA4_Click(object sender, RoutedEventArgs e)
        {
            if (editorManager == null)
            {
                MessageBox.Show("　　未找到页面管理器。", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (editorManager.PageCount <= 0)
            {
                MessageBox.Show("　　页面管理器中无页面。", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (editorManager.DocumentBackground != Brushes.White &&
                editorManager.DocumentBackground != BrushManager.DefaultImageBrush)
            {
                MessageBoxResult r = MessageBox.Show("　　当前文档的背景不是白色或默认底色，可能较浪费打印耗材，确定要继续吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
                if (r != MessageBoxResult.Yes) return;
            }

            //if (editorManager.AssistGridForm != AssistGridForm.None &&
            //    editorManager.AssistGridForm != AssistGridForm.Box)
            //{
            //    MessageBoxResult r = MessageBox.Show("　　一般不需要连同辅助线打印，确定要继续吗？",
            //        Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
            //    if (r != MessageBoxResult.Yes) return;
            //}

            List<PageEditor> allPages = editorManager.GetAllPageEditors();

            PaperInfo a4PaperInfo = PaperInfo.GetPaperInfo("A4");

            int validatePageCount = 0;
            foreach (PageEditor pe in allPages)
            {
                if (pe.PaperSize.PaperTypeName == "A4" || pe.PaperSize.PaperTypeName == "A3")
                {
                    validatePageCount++;
                }
                else if (pe.PaperSize.LongSideWPFUnit < a4PaperInfo.LongSideWPFUnit &&
                   pe.PaperSize.ShortSideWPFUnit < a4PaperInfo.ShortSideWPFUnit)
                {
                    validatePageCount++;
                }
            }

            if (validatePageCount == 0)
            {
                MessageBox.Show("　　没有找到尺寸为A4（或小于A4）或A3的任何页面。\r\n" +
                "　　此功能只能打印A4（或小于A4）或A3幅面，且A3会被缩小成A4。\r\n\r\n" +
                    "　　如果有其它打印需求，请导出（另存为）tiff格式的图片并自行打印。",
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (validatePageCount != allPages.Count)
            {
                MessageBoxResult r = MessageBox.Show(
                    string.Format("　　只有【{0}】个尺寸为A4（或小于A4）或A3的页面会被打印，" +
                    "　　此功能只支持A4（或小于A4）或A3幅面，且A3会被缩小成A4。\r\n\r\n", validatePageCount) +
                    "　　如有其它打印需求，请导出（另存为）tiff格式的图片并自行打印。",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (r != MessageBoxResult.Yes) return;
            }

            //准备打印
            PrintDialog printDialog = new PrintDialog();
            if (printDialog.ShowDialog() != true)
            {
                this.Activate();
                MainScrollViewer.Focus();//防止快捷键失效。
                return;
            }

            try
            {
                MainScrollViewer.Visibility = Visibility.Hidden;//避免变形时页面闪烁。
                TBPrintPrompt.Visibility = Visibility.Visible;

                foreach (PageEditor pe in allPages)
                {
                    bool validatePaperSize = false;
                    if (pe.PaperSize.PaperTypeName == "A4")
                    {
                        //System.Printing.PrintTicket ticket = printDialog.PrintTicket;
                        validatePaperSize = true;
                    }
                    else if (pe.PaperSize.PaperTypeName == "A3")
                    {
                        validatePaperSize = true;

                        double r = 1 / Math.Sqrt(2);
                        //主界面缩放使用的是ScaleTransform，因此这里不受影响。
                        pe.BaseCanvas.LayoutTransform = new ScaleTransform(r, r);
                        //A4的短边*Math.Sqrt(2)即为A3的短边。
                    }
                    else if (pe.PaperSize.ShortSideWPFUnit < a4PaperInfo.ShortSideWPFUnit &&
                        pe.PaperSize.LongSideWPFUnit < a4PaperInfo.LongSideWPFUnit)
                    {
                        validatePaperSize = true;//尺寸小于A4，无须缩放。
                    }

                    if (validatePaperSize == false) continue;//非A4或A3纸型，亦非小于A4的纸型。

                    if (pe.PaperDirection == Orientation.Horizontal)
                    {
                        printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
                        pe.BaseCanvas.Measure(new Size(printDialog.PrintableAreaHeight, printDialog.PrintableAreaWidth));
                        pe.BaseCanvas.Arrange(new Rect(new Point(0, 0), pe.BaseCanvas.DesiredSize));
                    }
                    else
                    {
                        printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Portrait;
                        pe.BaseCanvas.Measure(new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight));
                        pe.BaseCanvas.Arrange(new Rect(new Point(0, 0), pe.BaseCanvas.DesiredSize));
                    }

                    printDialog.PrintVisual(pe.BaseCanvas,
                        "Lunar Concept Printing:" + pe.Pagination.Text + editorManager.DefaultShortFileName);

                    if (pe.PaperSize.PaperTypeName == "A3")
                    {
                        pe.BaseCanvas.LayoutTransform = null;//恢复
                    }
                }

                MainScrollViewer.Visibility = Visibility.Visible;
                TBPrintPrompt.Visibility = Visibility.Hidden;

                MessageBox.Show(string.Format("　　已发送【{0}】个页面至选定的打印机！", validatePageCount), Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                foreach (PageEditor pe in allPages)
                {
                    if (pe.LayoutTransform != null) pe.LayoutTransform = null;//恢复。
                }

                MainScrollViewer.Visibility = Visibility.Visible;
                TBPrintPrompt.Visibility = Visibility.Hidden;

                MessageBox.Show("　　打印时出现异常。信息如下：\r\n" + ex.Message + ex.StackTrace,
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        private void RMIPrintSelectedPagesAsA4_Click(object sender, RoutedEventArgs e)
        {
            PrintSelectedPagesAsA4();
        }

        private void PrintSelectedPagesAsA4()
        {
            if (editorManager == null)
            {
                MessageBox.Show("　　未找到页面管理器。", Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (editorManager.PageCount <= 0)
            {
                MessageBox.Show("　　页面管理器中无页面。", Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (editorManager.DocumentBackground != Brushes.White &&
                editorManager.DocumentBackground != BrushManager.DefaultImageBrush)
            {
                MessageBoxResult r = MessageBox.Show("　　当前文档的背景不是白色或默认底色，可能较浪费打印耗材，确定要继续吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
                if (r != MessageBoxResult.Yes) return;
            }

            //if (editorManager.AssistGridForm != AssistGridForm.None &&
            //    editorManager.AssistGridForm != AssistGridForm.Box)
            //{
            //    MessageBoxResult r = MessageBox.Show("　　一般不需要连同辅助线打印，确定要继续吗？",
            //        Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
            //    if (r != MessageBoxResult.Yes) return;
            //}

            List<PageEditor> selectedPages = editorManager.GetSelectedPageEditorsList();

            PaperInfo a4PaperInfo = PaperInfo.GetPaperInfo("A4");

            int validatedPagesCount = 0;
            foreach (PageEditor pe in selectedPages)
            {
                if (pe.PaperSize.PaperTypeName == "A4" || pe.PaperSize.PaperTypeName == "A3")
                {
                    validatedPagesCount++;
                }
                else if (pe.PaperSize.LongSideWPFUnit < a4PaperInfo.LongSideWPFUnit &&//尺寸小于A4也可以。
                   pe.PaperSize.ShortSideWPFUnit < a4PaperInfo.ShortSideWPFUnit)
                {
                    validatedPagesCount++;
                }
            }

            if (validatedPagesCount == 0)
            {
                MessageBox.Show("　　没有选定任何页面，或者选定的页面中没有找到尺寸为A4（或小于A4）或A3的任何页面。\r\n" +
                "　　此功能只能打印A4（或小于A4）或A3幅面，且A3会被缩小为A4。\r\n\r\n" +
                    "　　如果有其它打印需求，请导出（另存为）tiff格式的图片并自行打印。",
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (validatedPagesCount != selectedPages.Count)
            {
                MessageBoxResult r = MessageBox.Show(string.Format("　　只有【{0}】个尺寸为A4（或小于A4）或A3的页面会被打印。\r\n" +
                    "　　此功能只支持A4（或小于A4）或A3幅面，且A3会被缩小为A4。\r\n\r\n", validatedPagesCount) +
                    "　　如有其它打印需求，请导出（另存为）tiff格式的图片并自行打印。",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (r != MessageBoxResult.Yes) return;
            }

            //准备打印
            PrintDialog printDialog = new PrintDialog();
            if (printDialog.ShowDialog() != true)
            {
                this.Activate();
                MainScrollViewer.Focus();
                return;
            }

            try
            {
                MainScrollViewer.Visibility = Visibility.Hidden;
                TBPrintPrompt.Visibility = Visibility.Visible;

                foreach (PageEditor pe in selectedPages)
                {
                    //if (mainPageEditor.PaperSize.PaperTypeName != "A4") continue;
                    //System.Printing.PrintTicket ticket = printDialog.PrintTicket;

                    bool validatePaperSize = false;
                    if (pe.PaperSize.PaperTypeName == "A4")
                    {
                        //System.Printing.PrintTicket ticket = printDialog.PrintTicket;
                        validatePaperSize = true;
                    }
                    else if (pe.PaperSize.PaperTypeName == "A3")
                    {
                        validatePaperSize = true;

                        double r = 1 / Math.Sqrt(2);
                        //主界面缩放使用的是ScaleTransform，因此这里不受影响。
                        pe.BaseCanvas.LayoutTransform = new ScaleTransform(r, r);
                        //A4的短边*Math.Sqrt(2)即为A3的短边。
                    }
                    else if (pe.PaperSize.ShortSideWPFUnit < a4PaperInfo.ShortSideWPFUnit &&
                       pe.PaperSize.LongSideWPFUnit < a4PaperInfo.LongSideWPFUnit)
                    {
                        validatePaperSize = true;//小于A4，不必缩放。
                    }

                    if (validatePaperSize == false) continue;//非A4或A3纸型，亦不是小于A4的纸型。

                    if (pe.PaperDirection == Orientation.Horizontal)
                    {
                        printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
                        pe.BaseCanvas.Measure(new Size(printDialog.PrintableAreaHeight, printDialog.PrintableAreaWidth));
                        pe.BaseCanvas.Arrange(new Rect(new Point(0, 0), pe.BaseCanvas.DesiredSize));
                        pe.BaseCanvas.InvalidateVisual();
                    }
                    else
                    {
                        printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Portrait;
                        pe.BaseCanvas.Measure(new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight));
                        pe.BaseCanvas.Arrange(new Rect(new Point(0, 0), pe.BaseCanvas.DesiredSize));
                        pe.BaseCanvas.InvalidateVisual();
                    }

                    printDialog.PrintVisual(pe.BaseCanvas,
                        "Lunar Concept Printing:" + pe.Pagination.Text + editorManager.DefaultShortFileName);

                    if (pe.PaperSize.PaperTypeName == "A3")
                    {
                        pe.BaseCanvas.LayoutTransform = null;//恢复
                    }
                }

                MainScrollViewer.Visibility = Visibility.Visible;
                TBPrintPrompt.Visibility = Visibility.Hidden;

                MessageBox.Show(string.Format("已发送【{0}】个页面至选定的打印机！", validatedPagesCount), Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                foreach (PageEditor pe in selectedPages)
                {
                    if (pe.LayoutTransform != null) pe.LayoutTransform = null;//恢复。
                }

                MainScrollViewer.Visibility = Visibility.Visible;
                TBPrintPrompt.Visibility = Visibility.Hidden;

                MessageBox.Show("　　打印时出现异常。信息如下：\r\n" + ex.Message + ex.StackTrace,
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        private void RMIPrintPages_Click(object sender, RoutedEventArgs e)
        {
            if (editorManager == null)
            {
                MessageBox.Show("　　未找到页面管理器。", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (editorManager.PageCount <= 0)
            {
                MessageBox.Show("　　页面管理器中无页面。", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (editorManager.DocumentBackground != Brushes.White &&
                editorManager.DocumentBackground != BrushManager.DefaultImageBrush)
            {
                MessageBoxResult r = MessageBox.Show("　　当前文档的背景不是白色或默认底色，可能较浪费打印耗材，确定要继续吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
                if (r != MessageBoxResult.Yes) return;
            }

            //if (editorManager.AssistGridForm != AssistGridForm.None &&
            //    editorManager.AssistGridForm != AssistGridForm.Box)
            //{
            //    MessageBoxResult r = MessageBox.Show("　　一般不需要连同辅助线打印，确定要继续吗？",
            //        Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
            //    if (r != MessageBoxResult.Yes) return;
            //}

            List<PageEditor> allPages = editorManager.GetAllPageEditors();

            if (allPages.Count <= 0)
            {
                LunarMessage.Warning("　　没有可打印的页面！");
                return;
            }

            //准备打印
            PrintDialog printDialog = new PrintDialog();
            if (printDialog.ShowDialog() != true)
            {
                this.Activate();
                MainScrollViewer.Focus();//防止快捷键失效。
                return;
            }

            try
            {
                foreach (PageEditor pe in allPages)
                {
                    if (pe.PaperDirection == Orientation.Horizontal)
                    {
                        printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
                        pe.BaseCanvas.Measure(new Size(printDialog.PrintableAreaHeight, printDialog.PrintableAreaWidth));
                        pe.BaseCanvas.Arrange(new Rect(new Point(0, 0), pe.BaseCanvas.DesiredSize));
                    }
                    else
                    {
                        printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Portrait;
                        pe.BaseCanvas.Measure(new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight));
                        pe.BaseCanvas.Arrange(new Rect(new Point(0, 0), pe.BaseCanvas.DesiredSize));
                    }

                    printDialog.PrintVisual(pe.BaseCanvas,
                        "Lunar Concept Printing:" + pe.Pagination.Text + editorManager.DefaultShortFileName);

                    if (pe.PaperSize.PaperTypeName == "A3")
                    {
                        pe.BaseCanvas.LayoutTransform = null;//恢复
                    }
                }

                MessageBox.Show(string.Format("　　已发送【{0}】个页面至选定的打印机！", allPages.Count), Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show("　　打印时出现异常。信息如下：\r\n" + ex.Message + ex.StackTrace,
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        private void RMIPrintSelectedPages_Click(object sender, RoutedEventArgs e)
        {
            PrintSelectedPages();
        }

        private void PrintSelectedPages()
        {
            if (editorManager == null)
            {
                MessageBox.Show("　　未找到页面管理器。", Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (editorManager.PageCount <= 0)
            {
                MessageBox.Show("　　页面管理器中无页面。", Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (editorManager.DocumentBackground != Brushes.White &&
                editorManager.DocumentBackground != BrushManager.DefaultImageBrush)
            {
                MessageBoxResult r = MessageBox.Show("　　当前文档的背景不是白色或默认底色，可能较浪费打印耗材，确定要继续吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
                if (r != MessageBoxResult.Yes) return;
            }

            //if (editorManager.AssistGridForm != AssistGridForm.None &&
            //    editorManager.AssistGridForm != AssistGridForm.Box)
            //{
            //    MessageBoxResult r = MessageBox.Show("　　一般不需要连同辅助线打印，确定要继续吗？",
            //        Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
            //    if (r != MessageBoxResult.Yes) return;
            //}

            List<PageEditor> selectedPages = editorManager.GetSelectedPageEditorsList();

            if (selectedPages.Count <= 0)
            {
                LunarMessage.Warning("　　没有选定任何页面。无法继续打印。");
            }

            //准备打印
            PrintDialog printDialog = new PrintDialog();
            if (printDialog.ShowDialog() != true)
            {
                this.Activate();
                MainScrollViewer.Focus();
                return;
            }

            try
            {
                foreach (PageEditor pe in selectedPages)
                {
                    if (pe.PaperDirection == Orientation.Horizontal)
                    {
                        printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
                        pe.BaseCanvas.Measure(new Size(printDialog.PrintableAreaHeight, printDialog.PrintableAreaWidth));
                        pe.BaseCanvas.Arrange(new Rect(new Point(0, 0), pe.BaseCanvas.DesiredSize));
                        pe.BaseCanvas.InvalidateVisual();
                    }
                    else
                    {
                        printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Portrait;
                        pe.BaseCanvas.Measure(new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight));
                        pe.BaseCanvas.Arrange(new Rect(new Point(0, 0), pe.BaseCanvas.DesiredSize));
                        pe.BaseCanvas.InvalidateVisual();
                    }

                    printDialog.PrintVisual(pe.BaseCanvas,
                        "Lunar Concept Printing:" + pe.Pagination.Text + editorManager.DefaultShortFileName);
                }

                MessageBox.Show(string.Format("已发送【{0}】个页面至选定的打印机！", selectedPages.Count), Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                MainScrollViewer.Visibility = Visibility.Visible;
                TBPrintPrompt.Visibility = Visibility.Hidden;

                MessageBox.Show("　　打印时出现异常。信息如下：\r\n" + ex.Message + ex.StackTrace,
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        private void RAMAbout_Click(object sender, RoutedEventArgs e)
        {
            AboutBox aboutBox = new AboutBox(this);
            aboutBox.ShowDialog();
        }

        private void GCPForeground_ColorPicked(object sender, ColorPickedEventArgs e)
        {
            LunarMessage.Warning(Commands.SetWidgetForeColorCommand.Execute(e.PickedColor));
        }

        private void GCPBackColor_ColorPicked(object sender, ColorPickedEventArgs e)
        {
            LunarMessage.Warning(Commands.SetWidgetBackColorCommand.Execute(e.PickedColor));
        }

        private void GCPLineColor_ColorPicked(object sender, ColorPickedEventArgs e)
        {
            LunarMessage.Warning(Commands.SetWidgetLineColorCommand.Execute(e.PickedColor));
        }

        private void SliderOfScale_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            MainScrollViewer.Focus();
            //避免部分快捷键失效问题（不是所有快捷键都使用自定义命令实现，因为自定义命令不支持单键快捷键）
        }

        private void RMIFormatTitleAsMainTitle_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.MainTitle);
            if (result != string.Empty)
            {
                MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n" + result, Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RMIFormatTitleAsT1_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T1);
            if (result != string.Empty)
            {
                MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n" + result, Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RMIFormatTitleAsT2_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T2);
            if (result != string.Empty)
            {
                MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n" + result, Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RMIFormatTitleAsT3_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T3);
            if (result != string.Empty)
            {
                MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n" + result, Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RMIFormatTitleAsT4_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T4);
            if (result != string.Empty)
            {
                MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n" + result, Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RMIFormatTitleAsT5_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.T5);
            if (result != string.Empty)
            {
                MessageBox.Show("　　格式化标题出错。异常信息如下：\r\n" + result, Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RMIFormatTitleAsNormal_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.FormatTitleCommand.FormatTitle(Enums.TitleStyle.Normal);
            if (result != string.Empty)
            {
                MessageBox.Show("　　格式化为正文时出错。异常信息如下：\r\n" + result, Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RBtnClearRecentFilesList_Click(object sender, RoutedEventArgs e)
        {
            if (System.IO.File.Exists(Globals.PathOfRecentlyFiles))
            {
                try
                {
                    System.IO.File.Delete(Globals.PathOfRecentlyFiles);
                    RecentFileItem.ReadRecentFilesFromXmlFile();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("　　未能顺利删除“最近文档列表”，异常信息如下：\r\n" + ex.Message,
                        Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
        }

        private void RMISetDefaultProperties_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.SetOneTypeOfWisgetStyleCommand.Execute();
            if (result != string.Empty)
            {
                MessageBox.Show("　　未能设置此类部件默认样式。错误信息如下：\r\n" + result,
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RMICancelDefaultProperties_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.ResetOneTypeOfWidgetStyleCommand.Execute();
            if (result != string.Empty)
            {
                MessageBox.Show("　　未能还原此类部件默认样式。错误信息如下：\r\n" + result,
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RMICancelAllDefaultProperties_Click(object sender, RoutedEventArgs e)
        {
            string result = Commands.ResetAllTypeOfWidgetsStyleCommand.Execute();
            if (result != string.Empty)
            {
                MessageBox.Show("　　未能还原所有部件默认样式。错误信息如下：\r\n" + result,
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void RMISaveWidgetStyleByName_Click(object sender, RoutedEventArgs e)
        {
            string result = SaveWidgetStyle();
            if (result != string.Empty)
            {
                MessageBox.Show("　　未能保存部件样式。错误信息如下：\r\n" + result,
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private string SaveWidgetStyle()
        {
            if (Globals.MainWindow == null) return "　　未找到Globals.MainWindow。";
            EditorManager manager = Globals.MainWindow.EditorManager;
            if (manager == null) return "　　未找到页面管理器。";

            PageEditor pe = manager.GetMainSelectedPageEditor();
            if (pe == null) return "　　未找到活动页面。";

            Widget mainSelWidget = pe.GetMainSelectedWidget();
            if (mainSelWidget == null) return "　　未找到活动部件。";

            ModifingInfo info = new ModifingInfo();
            info.ModifingDescription = "将当前部件样式指定为同类部件默认样式";
            manager.GetSelectedPageEditorStatus(info);
            manager.GetSelectedWidgetStatus_Old(info);
            manager.GetSelectedWidgetStatus_New(info);

            ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

            WidgetStyle newStyle = WidgetStyle.FromWidget(mainSelWidget);
            if (newStyle == null) return "　　未能从指定部件取出要设置的样式。";

            var ipr = InputBox.Show(Globals.AppName, "　　请为要保存的部件样式输入一个文件名称：", newStyle.WidgetClassName, false);
            if (string.IsNullOrWhiteSpace(ipr) == true) return "";  // 用户取消

            if (ipr.ToLower().EndsWith(".txt") == false)
                ipr += ".txt";

            try
            {
                if (Directory.Exists(Globals.PathOfUserStyles) == false)
                {
                    Directory.CreateDirectory(Globals.PathOfUserStyles);
                }

                bool removeSameNameItem = false;

                var path = Globals.PathOfUserStyles + ipr;
                if (File.Exists(path))
                {
                    var a = MessageBox.Show("已存在同名文件，要继续吗？", Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
                    if (a != MessageBoxResult.Yes) return "";  // 用户取消

                    removeSameNameItem = true;
                }

                using (StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8))
                {
                    sw.Write(newStyle.ToXML());
                }

                RefreshUserStyleToList(new UserStyleListItem(newStyle, ipr), removeSameNameItem);

                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private void RefreshUserStyleToList(UserStyleListItem newStyleItem, bool removeSameNameItem = false)
        {
            if (newStyleItem == null) return;

            // 是否删除同名的样式项目。
            if (removeSameNameItem)
            {
                for (int i = UserStylesListBox.Items.Count - 1; i >= 0; i--)
                {
                    var uli = UserStylesListBox.Items[i] as UserStyleListItem;
                    if (uli == null) continue;

                    if (uli.WidgetStyleFileName == newStyleItem.WidgetStyleFileName)
                    {
                        UserStylesListBox.Items.RemoveAt(i);
                        break;
                    }
                }
            }

            LoadUserStyles();
        }

        private void LoadUserStyles()
        {
            UserStylesListBox.Items.Clear();

            List<UserStyleListItem> list = new List<UserStyleListItem>();

            if (Directory.Exists(Globals.PathOfUserStyles) == false)
            {
                Directory.CreateDirectory(Globals.PathOfUserStyles);
            }

            var files = new DirectoryInfo(Globals.PathOfUserStyles).GetFiles("*.txt");
            foreach (var file in files)
            {
                var newUsli = new UserStyleListItem(file.FullName);
                list.Add(newUsli);
            }

            list.Sort(new UserStyleListItemComparer());

            var preWidgetClassName = "";
            foreach (var usli in list)
            {
                if (UserStylesListBox.Items.Count <= 0)
                {
                    UserStylesListBox.Items.Add(new ListBoxItem()
                    {
                        Content = usli.WidgetClassName,
                        Background = Brushes.DarkSlateBlue,
                        Foreground = Brushes.White,
                        IsEnabled = false,
                        Padding = new Thickness(4),
                    });
                    preWidgetClassName = usli.WidgetClassName;
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(preWidgetClassName) == false && preWidgetClassName != usli.WidgetClassName)
                    {
                        UserStylesListBox.Items.Add(new ListBoxItem()
                        {
                            Content = usli.WidgetClassName,
                            Background = Brushes.DarkSlateBlue,
                            Foreground = Brushes.White,
                            IsEnabled = false,
                            Padding = new Thickness(4),
                        });
                        preWidgetClassName = usli.WidgetClassName;
                    }
                }

                UserStylesListBox.Items.Add(usli);
            }
        }

        private void RibbonWindow_Drop(object sender, DragEventArgs e)
        {
            if (editorManager == null) return;

            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                Array dragDataArray = ((System.Array)e.Data.GetData(DataFormats.FileDrop));
                List<string> filenames = new List<string>();

                foreach (string s in dragDataArray)
                {
                    filenames.Add(s);
                }

                if (filenames.Count > 0)
                {
                    if (editorManager.IsModified)
                    {
                        MessageBoxResult mr = MessageBox.Show("当前文档已被修改，要保存吗？", Globals.AppName,
                            MessageBoxButton.YesNoCancel, MessageBoxImage.Warning, MessageBoxResult.Yes);

                        switch (mr)
                        {
                            case MessageBoxResult.Yes:
                                {
                                    string saveResult = Commands.SaveDocumentCommand.Execute();

                                    if (saveResult == Commands.SaveDocumentCommand.CancelSaveMessage)
                                    {
                                        return;
                                    }
                                    else if (saveResult == string.Empty)
                                    {
                                        Commands.OpenDocumentCommand.Execute(filenames[0]);
                                    }
                                    else
                                    {
                                        MessageBox.Show("　　未能保存当前文档。异常信息如下：\r\n" + saveResult,
                                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                                        return;
                                    }

                                    break;
                                }
                            case MessageBoxResult.No:
                                {
                                    LunarMessage.Warning(Commands.OpenDocumentCommand.Execute(filenames[0]));
                                    break;
                                }
                            default:
                                {
                                    return;//其余都作Cancel看待。
                                }
                        }
                    }
                    else
                    {
                        LunarMessage.Warning(Commands.OpenDocumentCommand.Execute(filenames[0]));
                    }
                }

                e.Handled = true;
            }
        }

        private void SdRotateText_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            Commands.SetTextRotateAngleCommand.Execute(SdRotateText.Value);
        }

        private void SdRotateText_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            Commands.SetTextRotateAngleCommand.Execute(0);
        }

        private void RMIFillBlankHelp_Click(object sender, RoutedEventArgs e)
        {
            Commands.ShowHelpCommand.ShowHelpPage("FillBlank");
        }

        private void MiBoldOn_Click(object sender, RoutedEventArgs e)
        {
            LunarMessage.Warning(Commands.TextCommands.RunTextCommand.Run("bold k"));
        }

        private void MiBoldOff_Click(object sender, RoutedEventArgs e)
        {
            LunarMessage.Warning(Commands.TextCommands.RunTextCommand.Run("bold g"));
        }

        private void MiItalicOn_Click(object sender, RoutedEventArgs e)
        {
            LunarMessage.Warning(Commands.TextCommands.RunTextCommand.Run("italic k"));
        }

        private void MiItalicOff_Click(object sender, RoutedEventArgs e)
        {
            LunarMessage.Warning(Commands.TextCommands.RunTextCommand.Run("italic g"));
        }

        private void MiUnderLineOn_Click(object sender, RoutedEventArgs e)
        {
            LunarMessage.Warning(Commands.TextCommands.RunTextCommand.Run("underline k"));
        }

        private void MiUnderLineOff_Click(object sender, RoutedEventArgs e)
        {
            LunarMessage.Warning(Commands.TextCommands.RunTextCommand.Run("underline g"));
        }

        private void MiStrikeLineOn_Click(object sender, RoutedEventArgs e)
        {
            LunarMessage.Warning(Commands.TextCommands.RunTextCommand.Run("strikeline k"));
        }

        private void MiStrikeLineOff_Click(object sender, RoutedEventArgs e)
        {
            LunarMessage.Warning(Commands.TextCommands.RunTextCommand.Run("strikeline g"));
        }

        private void CmbFontSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CmbFontSize.SelectedIndex < 0) return;
            try
            {
                double newFontSize = double.Parse((CmbFontSize.SelectedItem as ComboBoxItem).Content as string);

                if (newFontSize < 10 || newFontSize > 96)
                {
                    MessageBox.Show("　　部件字号应在[10,96]之间。", Globals.AppName,
                     MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                LunarMessage.Warning(Commands.TextCommands.RunTextCommand.Run("fontsize " + newFontSize.ToString()));
            }
            catch (Exception ex)
            {
                MessageBox.Show("　　【强行设置部件字号】操作出错！异常信息如下：\r\n" + ex.Message, Globals.AppName,
                     MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            finally
            {
                MainScrollViewer.Focus();
            }
        }

        private void CmbFontNames_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CmbFontNames.SelectedItem == null) return;

            string fontName = (CmbFontNames.SelectedItem as FontInfo).FontName;
            if (string.IsNullOrEmpty(fontName)) return;

            string result = Commands.TextCommands.RunTextCommand.Run("fontfamily " + fontName);
            if (result != string.Empty)
            {
                MessageBox.Show(result, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            CmbFontNames.SelectedIndex = -1;//准备下次

            MainScrollViewer.Focus();
        }

        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnNoneAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    if (RBtnNoneAssistGrid.Tag == null || RBtnNoneAssistGrid.Tag.ToString() != "Unalbe")
        //    {
        //        Commands.SetAssistGridFormCommand.Execute(AssistGridForm.None);
        //    }
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnBoxAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    if (RBtnBoxAssistGrid.Tag == null || RBtnBoxAssistGrid.Tag.ToString() != "Unalbe")
        //    {
        //        Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Box);
        //    }
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RRBtnGridAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    if (RRBtnGridAssistGrid.Tag == null || RRBtnGridAssistGrid.Tag.ToString() != "Unalbe")
        //    {
        //        Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Grid);
        //    }
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnTianziAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    if (RBtnTianziAssistGrid.Tag == null || RBtnTianziAssistGrid.Tag.ToString() != "Unalbe")
        //    {
        //        Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Tianzi);
        //    }
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnHuiziAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    if (RBtnHuiziAssistGrid.Tag == null || RBtnHuiziAssistGrid.Tag.ToString() != "Unalbe")
        //    {
        //        Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Huizi);
        //    }
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnHuiTianAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    if (RBtnHuiTianAssistGrid.Tag == null || RBtnHuiTianAssistGrid.Tag.ToString() != "Unalbe")
        //    {
        //        Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Huitian);
        //    }
        //}

        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //public void RefreshAssistGridFormButtons(AssistGridForm newGridForm)
        //{
        //    RBtnNoneAssistGrid.Tag =
        //        RBtnBoxAssistGrid.Tag =
        //        RRBtnGridAssistGrid.Tag =
        //        RBtnTianziAssistGrid.Tag =
        //        RBtnHuiziAssistGrid.Tag =
        //        RBtnHuiTianAssistGrid.Tag = "Unable";

        //    RBtnNoneAssistGrid.IsChecked =
        //        RBtnBoxAssistGrid.IsChecked =
        //        RRBtnGridAssistGrid.IsChecked =
        //        RBtnTianziAssistGrid.IsChecked =
        //        RBtnHuiziAssistGrid.IsChecked =
        //        RBtnHuiTianAssistGrid.IsChecked = false;

        //    switch (newGridForm)
        //    {
        //        case AssistGridForm.Box:
        //            {
        //                RBtnBoxAssistGrid.IsChecked = true; break;
        //            }
        //        case AssistGridForm.Grid:
        //            {
        //                RRBtnGridAssistGrid.IsChecked = true; break;
        //            }
        //        case AssistGridForm.Huitian:
        //            {
        //                RBtnHuiTianAssistGrid.IsChecked = true; break;
        //            }
        //        case AssistGridForm.Huizi:
        //            {
        //                RBtnHuiziAssistGrid.IsChecked = true; break;
        //            }
        //        case AssistGridForm.None:
        //            {
        //                RBtnNoneAssistGrid.IsChecked = true; break;
        //            }
        //        case AssistGridForm.Tianzi:
        //            {
        //                RBtnTianziAssistGrid.IsChecked = true; break;
        //            }
        //    }

        //    //恢复
        //    RBtnNoneAssistGrid.Tag =
        //         RBtnBoxAssistGrid.Tag =
        //         RRBtnGridAssistGrid.Tag =
        //         RBtnTianziAssistGrid.Tag =
        //         RBtnHuiziAssistGrid.Tag =
        //         RBtnHuiTianAssistGrid.Tag = null;
        //}

        private void GSLeftTools_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            RefreshOutlineView();//刷新大纲视图
            RefreshPageView();//刷新页面视图

            this.MainScrollViewer.Focus();
        }

        private void GSRightTools_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            this.MainScrollViewer.Focus();
        }

        private void MiRefreshOutLine_Click(object sender, RoutedEventArgs e)
        {
            this.RefreshOutlineView(true);
        }

        private void MiCopyOutLine_Click(object sender, RoutedEventArgs e)
        {
            Dialogs.OutLineDialog odlg = new OutLineDialog(this);

            //将所有段落添加到odlg的文档中。
            List<List<Widgets.TextArea>> textAreaLists = new List<List<Widgets.TextArea>>();
            foreach (UIElement peUI in this.editorManager.Children)
            {
                PageEditor pe = peUI as PageEditor;
                if (pe == null) continue;

                List<Widgets.TextArea> textAreaList = pe.GetAllTextAreaWidgets();
                textAreaLists.Add(textAreaList);
            }

            if (textAreaLists.Count <= 0) return;

            FontWeight fontWeight;
            FontStyle fontStyle = FontStyles.Normal;//全用Normal
            FontFamily fontFamily;
            double fontSize = this.editorManager.DefaultFontSize;

            foreach (List<Widgets.TextArea> textAreaList in textAreaLists)
            {
                if (textAreaList == null || textAreaList.Count <= 0) continue;

                foreach (Widgets.TextArea tw in textAreaList)
                {
                    if (tw.MasterEditor == null) continue;
                    if (tw.MasterEditor.MasterManager == null) continue;
                    if (tw.TitleLevel == Enums.TitleStyle.Normal) continue;

                    fontWeight = TitleManager.GetFontWeight(tw.TitleLevel);
                    fontFamily = TitleManager.GetFontFamily(tw.TitleLevel);
                    fontSize = TitleManager.GetFontSize(tw.TitleLevel);

                    Paragraph p = new Paragraph(
                        new Run(tw.Text)
                        {
                            FontFamily = fontFamily,
                            FontSize = fontSize,
                            FontWeight = fontWeight,
                        });

                    p.TextIndent = (int)tw.TitleLevel * 2 * this.editorManager.DefaultFontSize;

                    odlg.AddParagraph(p);
                }
            }


            odlg.ShowDialog();
        }

        private void MiRefreshPageView_Click(object sender, RoutedEventArgs e)
        {
            this.RefreshPageView();
        }

        private void RBtnFormatFillBlankText_Click(object sender, RoutedEventArgs e)
        {
            FormatFillBlankTextWindow fftw = new FormatFillBlankTextWindow() { Owner = this };
            fftw.Show();
        }

        private void RBtnExplorerToInstallFolder_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("explorer.exe", $"\"{Globals.InstalledPath}\"");
        }

        private void RBtnExplorerToUserDataFolder_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("explorer.exe", $"\"{Globals.PathOfUserDirectory}\"");
        }

        private string quickSavePageImagePath = "";

        private void RBtnSetFolderToSavePageImage_Click_1(object sender, RoutedEventArgs e)
        {
            TextInputBox tiBox = new TextInputBox(this, "请输入默认的“页面图保存目录”：", Globals.AppName, "");
            if (tiBox.ShowDialog() == true)
            {
                this.quickSavePageImagePath = tiBox.TbxInput.Text;
            }
        }

        private void SavePageImageAndBuildHyperLinkTextToClipboard_Click_1(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(this.quickSavePageImagePath))
            {
                LunarMessage.Warning("　　请先设置快速保存页面图的路径！");
                return;
            }

            if (this.quickSavePageImagePath.EndsWith("\\") == false)
            {
                this.quickSavePageImagePath += "\\";
            }

            if (Directory.Exists(this.quickSavePageImagePath) == false)
            {
                LunarMessage.Warning("　　设置的快速保存路径无效！");
                return;
            }

            PageEditor mainSelPageEditor = this.editorManager.GetMainSelectedPageEditor();
            if (mainSelPageEditor == null)
            {
                LunarMessage.Warning("　　未找到主选定页面，无法继续！");
            }

            string saveResult = Commands.OutportMainPageToImageFileCommand.Execute
                (this.quickSavePageImagePath + mainSelPageEditor.Id + "." + Globals.ExtensionNameOfOutportPng);

            if (saveResult != string.Empty)
            {
                LunarMessage.Warning(saveResult);
                return;
            }

            string lastFolderShortName;

            this.quickSavePageImagePath = this.quickSavePageImagePath.Substring(0, this.quickSavePageImagePath.Length - 1);
            int lastIndex = this.quickSavePageImagePath.LastIndexOf('\\');
            if (lastIndex < 0)
            {
                LunarMessage.Warning("　　快速保存路径无效，无法生成链接文本。");
                return;
            }

            lastFolderShortName = this.quickSavePageImagePath.Substring(lastIndex + 1);

            if (string.IsNullOrEmpty(lastFolderShortName))
            {
                LunarMessage.Warning("　　快速保存路径无效，无法生成链接文本。");
                return;
            }

            try
            {
                string aText = "<div style=\"text-align:center\"><img src=\"" + lastFolderShortName + "/" +
                    mainSelPageEditor.Id + "." + Globals.ExtensionNameOfOutportPng + "\"" + " /></div>";
                Clipboard.SetData(DataFormats.UnicodeText, aText);
                LunarMessage.Information("已在剪贴板中生成HTML字符串：\r\n\r\n" + aText);
            }
            catch (Exception ex)
            {
                LunarMessage.Warning(ex.Message);
            }
        }

        private void RBtnBroseFolderToSavePageImage_Click_1(object sender, RoutedEventArgs e)
        {
            System.OperatingSystem osInfo = System.Environment.OSVersion;

            //          case 6:  
            //               switch (osInfo.Version.Minor)  
            //               {  
            //                   case 0:  
            //                       version = WindowsVersion.Vista;  
            //                       break;  
            //                   default:  
            //                       version = WindowsVersion.Win7;  
            //                       break;  
            //                }  

            if (osInfo.Version.Major < 6)
            {
                LunarMessage.Warning("　　此功能仅在Windows Vista及更高版本的操作系统中有效！");
                return;
            }

            CommonOpenFileDialog cfd = new CommonOpenFileDialog()
            {
                Title = Globals.AppName
            };

            cfd.EnsureReadOnly = true;
            cfd.IsFolderPicker = true;
            cfd.AllowNonFileSystemItems = true;

            if (cfd.ShowDialog() == CommonFileDialogResult.Ok)
            {
                ShellContainer selectedSO = null;

                try
                {
                    // Try to get a valid selected item
                    selectedSO = cfd.FileAsShellObject as ShellContainer;
                }
                catch
                {
                    MessageBox.Show("Could not create a ShellObject from the selected item");
                }

                // Set the path in our filename textbox
                this.quickSavePageImagePath = selectedSO.ParsingName;
            }
        }

        private void ImgShowMagnifier_MouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
        {
            if (this.magnifierControlPanel == null) return;

            this.magnifierControlPanel.IsOpen = !this.magnifierControlPanel.IsOpen;
        }

        private void RBtnCopySelectedAreaToImage_Click(object sender, RoutedEventArgs e)
        {
            if (this.editorManager == null) return;
            this.editorManager.CopySelectedAreaToImage = RBtnCopySelectedAreaToImage.IsChecked == true ? true : false;
        }

        private void Border_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            //由于ScrollViewer自身带的快捷键与程序快捷键存在冲突，
            //因此四个方向键的处理只能放在这个事件处理器中
            //（必须在ScrollViewer外部，窗口不合适，而且不应是KeyUp事件）。
            //本来是放在窗口的，但问题在于，这样会导致无法使用上下键在“命令列表”中翻下一项。

            bool isShift = false;
            KeyStates ksLeftShift = Keyboard.GetKeyStates(Key.LeftShift);
            KeyStates ksRightShift = Keyboard.GetKeyStates(Key.RightShift);
            if ((ksLeftShift & KeyStates.Down) > 0 || (ksRightShift & KeyStates.Down) > 0) isShift = true;

            bool isCtrl = false;
            KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
            KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);
            if ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0) isCtrl = true;

            bool isAlt = false;
            KeyStates ksLeftAlt = Keyboard.GetKeyStates(Key.LeftAlt);
            KeyStates ksRightAlt = Keyboard.GetKeyStates(Key.RightAlt);
            if ((ksLeftAlt & KeyStates.Down) > 0 || (ksRightAlt & KeyStates.Down) > 0) isAlt = true;


            switch (e.Key)
            {
                case Key.Up:
                    {
                        if (isCtrl)
                        {
                            if (isAlt == false)
                            {
                                if (isShift)
                                {
                                    Commands.SizeCollapseToTopCommand.Execute(10);
                                }
                                else
                                {
                                    MainScrollViewer.ScrollToVerticalOffset(MainScrollViewer.VerticalOffset - 30);
                                }
                                e.Handled = true;
                            }
                        }
                        else
                        {
                            if (isShift && isAlt == false)
                            {
                                Commands.SizeCollapseToTopCommand.Execute();
                                e.Handled = true;
                            }
                        }
                        break;
                    }
                case Key.Down:
                    {
                        if (isCtrl)
                        {
                            if (isAlt == false)
                            {
                                if (isShift)
                                {
                                    Commands.SizeExpandToBottomCommand.Execute(10);
                                }
                                else
                                {
                                    MainScrollViewer.ScrollToVerticalOffset(MainScrollViewer.VerticalOffset + 30);
                                }
                                e.Handled = true;
                            }
                        }
                        else
                        {
                            if (isShift && isAlt == false)
                            {
                                Commands.SizeExpandToBottomCommand.Execute();
                                e.Handled = true;
                            }
                        }
                        break;
                    }
                case Key.Left:
                    {
                        if (isCtrl)
                        {
                            if (isAlt == false)
                            {
                                if (isShift)
                                {
                                    Commands.SizeCollapseToLeftCommand.Execute(10);
                                }
                                else
                                {
                                    MainScrollViewer.ScrollToHorizontalOffset(MainScrollViewer.HorizontalOffset - 30);
                                }
                                e.Handled = true;
                            }
                        }
                        else
                        {
                            if (isShift && isAlt == false)
                            {
                                Commands.SizeCollapseToLeftCommand.Execute();
                                e.Handled = true;
                            }
                        }
                        break;
                    }
                case Key.Right:
                    {
                        if (isCtrl)
                        {
                            if (isAlt == false)
                            {
                                if (isShift)
                                {
                                    Commands.SizeExpandToRightCommand.Execute(10);
                                }
                                else
                                {
                                    MainScrollViewer.ScrollToHorizontalOffset(MainScrollViewer.HorizontalOffset + 30);
                                }
                                e.Handled = true;
                            }
                        }
                        else
                        {
                            if (isShift && isAlt == false)
                            {
                                Commands.SizeExpandToRightCommand.Execute();
                                e.Handled = true;
                            }
                        }
                        break;
                    }
            }
        }

        private void RBtnHideWidgetText_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetTextVisibleOffCommand.SetSelectedWidgetsTextVisibleOff();
        }

        private void RBtnHideAllWidgetsTextInActivePage_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetTextVisibleOffCommand.SetAllWidgetsInMainSelectedPageTextVisibleOff();
        }

        private void RBtnHideAllWidgetsTextInDocument_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetTextVisibleOffCommand.SetAllWidgetsInWholeDocumentTextVisibleOff();
        }

        private void RBtnShowWidgetText_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetTextVisibleOnCommand.SetSelectedWidgetsTextVisibleOn();
        }

        private void RBtnShowAllWidgetsTextInActivePage_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetTextVisibleOnCommand.SetAllWidgetsInMainSelectedPageTextVisibleOn();
        }

        private void RBtnShowAllWidgetsTextInDocument_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetTextVisibleOnCommand.SetAllWidgetsInWholeDocumentTextVisibleOn();
        }

        private void RBtnSwitchOnFillblankOfWidget_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetFillBlankModeOnCommand.SetSelectedWidgetsFillBlankModeOn();
        }

        private void RBtnSwitchOnFillblankInActivePage_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetFillBlankModeOnCommand.SetAllWidgetsInMainSelectedPageFillBlankModeOn();
        }

        private void RBtnSwitchOnFillblankInDocument_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetFillBlankModeOnCommand.SetWidgetsInWholeDocumentFillBlankModeOn();
        }

        private void RBtnSwitchOffFillblankOfWidget_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetFillBlankModeOffCommand.SetSelectedWidgetsFillBlankModeOff();
        }

        private void RBtnSwitchOffFillblankInActivePage_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetFillBlankModeOffCommand.SetAllWidgetsInMainSelectedPageFillBlankModeOff();
        }

        private void RBtnSwitchOffFillblankInDocument_Click(object sender, RoutedEventArgs e)
        {
            Commands.SetWidgetFillBlankModeOffCommand.SetWidgetsInWholeDocumentFillBlankModeOff();
        }

        private void RBtnOfFillBlankHelp_Click(object sender, RoutedEventArgs e)
        {
            Commands.ShowHelpCommand.ShowHelpPage("FillBlank");
        }

        private void RBtnScrollToFirstPage_Click(object sender, RoutedEventArgs e)
        {
            this.MainScrollViewer.ScrollToFirstPage();
        }

        private void RBtnScrollToPreviewPage_Click(object sender, RoutedEventArgs e)
        {
            this.MainScrollViewer.ScrollToPreviewPage();
        }

        private void RBtnScrollToNextPage_Click(object sender, RoutedEventArgs e)
        {
            this.MainScrollViewer.ScrollToNextPage();
        }

        private void RBtnScrollToLastPage_Click(object sender, RoutedEventArgs e)
        {
            this.MainScrollViewer.ScrollToLastPage();
        }

        void editorManager_MainSelectedPageChanged(object sender, MainSelectedPageEditorChangedEventArgs e)
        {
            if (e.PageEditor != null)
            {
                // 记录当前页的Comment
                if (PageCommentEditor.IsModified)// && e.PageEditor != editorManager.PreviewMainSelectedPageEditor)
                {
                    //为什么要去除这个条件呢？这是因为，修改了当前页的备注后，再点击当前页时，如果不更新当前页的CommentText，会导致重新载入，这时候，修改的内容就被抛弃了。
                    UpdatePageCommentText(editorManager.PreviewMainSelectedPageEditor);
                }

                // 载入新活动页面的Comment

                PageCommentEditor.Text = XmlTools.RestoreXmlChars(e.PageEditor.CommentText);
                PageCommentEditor.IsModified = false;
                PageCommentEditor.Document.UndoStack.ClearAll();
                PageCommentEditor.Document.UndoStack.MarkAsOriginalFile();

                foreach (var ue in RGpViewAssistGridForm.Items)
                {
                    var button = ue as RibbonRadioButton;
                    if (button == null) continue;

                    button.IsChecked = (button.Tag.ToString() == e.PageEditor.AssistGridForm.ToString());
                }
            }
            else
            {
                foreach (var ue in RGpViewAssistGridForm.Items)
                {
                    var button = ue as RibbonRadioButton;
                    if (button != null) button.IsChecked = false;
                }

                PageCommentEditor.Text = "";
                PageCommentEditor.IsModified = false;
                PageCommentEditor.Document.UndoStack.ClearAll();
                PageCommentEditor.Document.UndoStack.MarkAsOriginalFile();
            }
        }

        public void UpdatePageCommentText(PageEditor mainPe)
        {
            if (mainPe == null) return;

            if (PageCommentEditor.IsModified)
            {
                ModifingInfo info = new ModifingInfo();
                editorManager.GetSelectedPageEditorStatus(info);
                editorManager.GetSelectedWidgetStatus_Old(info);
                editorManager.GetSelectedWidgetStatus_New(info);

                info.ModifingDescription = "设置页面备注";

                ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);
                mi.ModifingInfo.OldMainSelectedPageEditorID = mainPe.Id;
                mi.ModifingInfo.NewMainSelectedPageEditorID = mainPe.Id;
                //设置备注时，是不会更改页面的。例如插入新页前会更新备注，但重做备注时，因为新页尚未恢复，重做操作无法定位——所以不能传入新页ID。

                string newPageCommentText = XmlTools.ReplaceXmlChars(PageCommentEditor.Text);

                Action actPageCommentText = new Action(ActionType.SetPageCommentText, mainPe.Id,
                    mainPe.CommentText, newPageCommentText);
                mainPe.CommentText = newPageCommentText;
                mi.AddAction(actPageCommentText);

                editorManager.RegisterModifingItem(mi);

                PageCommentEditor.IsModified = false;//复位
                PageCommentEditor.Document.UndoStack.ClearAll();
                PageCommentEditor.Document.UndoStack.MarkAsOriginalFile();
            }
        }

        private void ImgShowPageCommentEditArea_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (CommentRowDefinition.ActualHeight < 20)
            {
                CommentRowDefinition.Height = new GridLength(100);
                PageCommentEditor.Focus();
            }
            else
            {
                CommentRowDefinition.Height = new GridLength(10);
            }
        }

        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnTwoLineAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    //if (RBtnHuiTianAssistGrid.Tag == null || RBtnHuiTianAssistGrid.Tag.ToString() != "Unalbe")
        //    //{
        //    Commands.SetAssistGridFormCommand.Execute(AssistGridForm.TwoLine);
        //    //}
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnTwoColumnAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    Commands.SetAssistGridFormCommand.Execute(AssistGridForm.TwoColumn);
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnThreeLineAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    Commands.SetAssistGridFormCommand.Execute(AssistGridForm.ThreeLine);
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnThreeColumnAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    Commands.SetAssistGridFormCommand.Execute(AssistGridForm.ThreeColumn);
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnFourCellAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    Commands.SetAssistGridFormCommand.Execute(AssistGridForm.FourCell);
        //}
        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        ///// <param name="newGridForm"></param>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RBtnNineCellAssistGrid_Checked(object sender, RoutedEventArgs e)
        //{
        //    Commands.SetAssistGridFormCommand.Execute(AssistGridForm.NineCell);
        //}

        private void RBtnAssistGrid_Clicked(object sender, RoutedEventArgs e)
        {
            RibbonRadioButton rBtn = sender as RibbonRadioButton;
            if (rBtn == null || rBtn.IsChecked != true) return;

            if (rBtn == RBtnNoneAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.None);
            }
            else if (rBtn == RBtnBoxAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Box);
            }
            else if (rBtn == RRBtnGridAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Grid);
            }
            else if (rBtn == RBtnTianziAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Tianzi);
            }
            else if (rBtn == RBtnHuiziAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Huizi);
            }
            else if (rBtn == RBtnHuiTianAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.Huitian);
            }
            else if (rBtn == RBtnTwoLineAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.TwoLine);
            }
            else if (rBtn == RBtnTwoColumnAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.TwoColumn);
            }
            else if (rBtn == RBtnThreeLineAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.ThreeLine);
            }
            else if (rBtn == RBtnThreeColumnAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.ThreeColumn);
            }
            else if (rBtn == RBtnFourCellAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.FourCell);
            }
            else if (rBtn == RBtnNineCellAssistGrid)
            {
                Commands.SetAssistGridFormCommand.Execute(AssistGridForm.NineCell);
            }
        }

        private int presentationPoint = -1;

        private bool isPresentatingByPath = false;
        /// <summary>
        /// 是否正在按指定区域演示中。
        /// </summary>
        public bool IsPresentatingByPath
        {
            get
            {
                return isPresentatingByPath;
            }
        }

        private void PresentateByPath(int point)
        {
            if (point < 0 || point >= presentationAreas.Count)
            {
                ExitPresentationByPath();
                return;
            }

            var area = presentationAreas[point];
            if (area.RealRect.Width <= 20 || area.RealRect.Height <= 20)
            {
                presentationPoint++;
                return;
            }

            if (presentationPoint >= 0 && presentationPoint < presentationAreas.Count)
            {
                presentatingWidgets = GetWidgetsWithCommentInPresentationArea(area);
            }

            PresentateArea(area);
        }

        private void PresentateArea(RectangleWidget area)
        {
            //设置文本渲染显示方式为适合缩放。
            TextOptions.SetTextFormattingMode(MainScrollViewer, TextFormattingMode.Ideal);

            //先回归正常比例
            this.SliderOfScale.Value = 0;

            double scale = 1;

            //if (area.MasterEditor.PaperSizeText.StartsWith("custom") == false)
            //{
            var screenRate = Globals.MainWindow.MainScrollViewer.ViewportWidth / Globals.MainWindow.MainScrollViewer.ViewportHeight;
            var areaRate = area.RealRect.Width / area.RealRect.Height;


            if (areaRate > screenRate)
            {
                //应使用长边
                scale = area.RealRect.Width / Globals.MainWindow.MainScrollViewer.ViewportWidth;
            }
            else
            {
                scale = area.RealRect.Height / Globals.MainWindow.MainScrollViewer.ViewportHeight;
            }

            if (scale == 0) return;

            scale = 1 / scale;
            //}

            this.SliderOfScale.Value = ScaleValueConverter.RestoreScaleValue(scale);

            //滚动显示对应的被标记为“演示区域”的矩形部件。
            PresentateWidgetInScrollViewer(area, scale);
        }

        private void PresentateWidgetInScrollViewer(RectangleWidget area, double scale)
        {
            if (area == null || area.MasterEditor == null) return;
            //直接居中显示即可

            area.MasterEditor.HideAssistGridForm();

            this.MainScrollViewer.InvalidateMeasure();
            this.MainScrollViewer.UpdateLayout();

            var areaTopLeft = (area.Parent as Canvas).TranslatePoint(area.TopLeft, this.MainScrollViewer);

            //this.MainScrollViewer.ScrollToHorizontalOffset(this.MainScrollViewer.HorizontalOffset + areaTopLeft.X
            //    - (this.MainScrollViewer.ViewportWidth - area.RealRect.Width * scale) / 2);
            //this.MainScrollViewer.ScrollToVerticalOffset(this.MainScrollViewer.VerticalOffset + areaTopLeft.Y
            //    - (this.MainScrollViewer.ViewportHeight - area.RealRect.Height * scale) / 2);

            var x = this.MainScrollViewer.HorizontalOffset + areaTopLeft.X
                - (this.MainScrollViewer.ViewportWidth - area.RealRect.Width * scale) / 2;
            var y = this.MainScrollViewer.VerticalOffset + areaTopLeft.Y
                - (this.MainScrollViewer.ViewportHeight - area.RealRect.Height * scale) / 2;

            ScrollToPosition(false, x, y);
        }

        private List<RectangleWidget> presentationAreas = new List<RectangleWidget>();

        public void GetPresentationAreas()
        {
            presentationPoint = -1;
            presentationAreas.Clear();

            foreach (UIElement ue in this.editorManager.Children)
            {
                var page = ue as PageEditor;
                if (page == null) continue;

                var widgets = page.GetAllWidgets();
                foreach (Widget w in widgets)
                {
                    var rw = w as RectangleWidget;
                    if (rw == null) continue;

                    if (rw.IsPresentationArea) presentationAreas.Add(rw);
                }
            }

            //演示时按MarkText的顺序来进行。
            if (presentationAreas.Count > 0)
            {
                presentationAreas.Sort(new RectangleWidgetMarkTextComparer());
            }
        }

        /// <summary>
        /// 查找当前文档中所有被定义为演示区的矩形部件，并按其顺序显示在左工具栏中。
        /// </summary>
        private void FindPresentationAreasInDocument()
        {
            lbxFindPresentationAreas.Items.Clear();

            var pas = new List<RectangleWidget>();
            foreach (UIElement ue in this.editorManager.Children)
            {
                var page = ue as PageEditor;
                if (page == null) continue;

                var widgets = page.GetAllWidgets();
                foreach (Widget w in widgets)
                {
                    var rw = w as RectangleWidget;
                    if (rw == null) continue;

                    if (rw.IsPresentationArea) pas.Add(rw);
                }
            }

            if (pas.Count > 0) pas.Sort(new RectangleWidgetMarkTextComparer());

            foreach (RectangleWidget rw in pas)
            {
                var pai = new PresentationAreaItem(rw);
                lbxFindPresentationAreas.Items.Add(pai);
            }
        }

        private List<Widget> GetWidgetsWithCommentInPresentationArea(RectangleWidget rw)
        {
            if (rw == null) return null;
            if (rw.MasterEditor == null) return null;
            if (rw.IsPresentationArea == false) return null;

            List<Widget> widgets = new List<Widget>();
            foreach (Widget widget in rw.MasterEditor.GetAllWidgets())
            {
                //没有备注文本的直接显示。
                if (string.IsNullOrEmpty(widget.CommentText)) continue;
                RectangleWidget subRw = widget as RectangleWidget;
                if (subRw != null && subRw.IsPresentationArea) continue;

                if (rw.RealRect.Contains(widget.RealRect))
                {
                    widgets.Add(widget);
                }
            }

            widgets.Sort(new WidgetCommentTextComparer());
            return widgets;
        }

        private double scaleSliderValueBeforePresentateByPath = -1;
        private double hOffsetBeforePresentateByPath = -1;
        private double vOffsetBeforePresentateByPath = -1;

        private void RTBtnStartPresentationByPath_Click(object sender, RoutedEventArgs e)
        {
            #region 用于按区域演示的过程中自动显示被隐藏的填空题文本等
            presentationHidedTextWidgets.Clear();
            presentationFillBlankWidgets.Clear();
            #endregion

            GetPresentationAreas();

            if (presentationAreas.Count <= 0)
            {
                //var answer = MessageBox.Show("没有找到自定义演示区域。要将页面本身当作演示区域进行演示吗？", Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
                //if (answer != MessageBoxResult.Yes) return;
                //else
                //{
                var index = 0;
                foreach (var pageEditor in EditorManager.GetAllPageEditors())
                {
                    var newTempArea = new RectangleWidget(pageEditor) { IsPresentationArea = true, };
                    newTempArea.StartPoint = new Point(0, 0);
                    newTempArea.EndPoint = new Point(pageEditor.ActualWidth, pageEditor.ActualHeight);
                    newTempArea.CommentText = index.ToString();
                    index++;

                    pageEditor.AddWidget(newTempArea);
                    tempPresentationAreas.Add(newTempArea);
                }

                // 再执行一遍
                GetPresentationAreas();
                if (presentationAreas.Count <= 0)
                {
                    MessageBox.Show("没有可以演示的自定义区域。", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
                //}
            }

            this.Ribbon.IsCollapsed = true;

            // 下面这些会造成演示时卡顿、点不开矩形部件标记文本等问题。
            //Ribbon.Visibility = Visibility.Collapsed;
            //rdRibbon.Height = new GridLength(0, GridUnitType.Pixel);
            DPStatus.Visibility = Visibility.Collapsed;
            rdStatus.Height = new GridLength(0, GridUnitType.Pixel);
            //this.WindowState = WindowState.Maximized;
            //this.WindowStyle = WindowStyle.None;

            //这个不起作用！！！
            //this.MainScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
            //this.MainScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
            //this.MainScrollViewer.InvalidateVisual();

            this.InvalidateArrange();
            this.UpdateLayout();

            HideAllWidgetsWithCommentText();

            //先缩放为100%，再移动，再缩放以显示此“演示区域”的内容。
            RTBtnStartPresentationByPath.IsEnabled = false;

            foreach (var area in presentationAreas)
            {
                area.Visibility = Visibility.Hidden;
            }

            //presentationPoint++;
            isPresentatingByPath = true;

            // 必须放在 isPresntatingByPath 后面调用！！！
            // 隐藏连接线，显示连接线的首尾标记，点击首尾标记时动画呈现，这样可以有“画线”效果。
            HideLinkedLines();

            scaleSliderValueBeforePresentateByPath = SliderOfScale.Value;
            hOffsetBeforePresentateByPath = this.MainScrollViewer.HorizontalOffset;
            vOffsetBeforePresentateByPath = this.MainScrollViewer.VerticalOffset;

            //PresentateByPath(presentationPoint);
            PresentateNextByPath();

            GridPresentationTools.Visibility = Visibility.Visible;
        }

        private void HideLinkedLines()
        {
            if (this.editorManager == null) return;
            var pages = this.editorManager.GetAllPageEditors();
            if (pages == null || pages.Count <= 0) return;

            foreach (var page in pages)
            {
                var widgets = page.GetAllWidgets();
                if (widgets == null || widgets.Count <= 0) continue;

                foreach (var widget in widgets)
                {
                    if (widget is Widgets.BezierLineWidget bLine)
                    {
                        if (Globals.MainWindow.rtbtnAutoHideBazeirLine.IsChecked == true)
                        {
                            bLine.IsPresentating = true;
                            bLine.StartPresentateAdorner.Visibility = Visibility.Visible;
                            bLine.StartPresentateAdorner.InvalidateVisual();
                            bLine.EndPresentateAdorner.Visibility = Visibility.Visible;
                            bLine.EndPresentateAdorner.InvalidateVisual();
                        }
                    }
                    else if (widget is Widgets.PolyLineWidget pLine)
                    {
                        if (Globals.MainWindow.rtbtnAutoHidePolyLine.IsChecked == true)
                        {
                            pLine.IsPresentating = true;
                            pLine.StartPresentateAdorner.Visibility = Visibility.Visible;
                            pLine.StartPresentateAdorner.InvalidateVisual();
                            pLine.EndPresentateAdorner.Visibility = Visibility.Visible;
                            pLine.EndPresentateAdorner.InvalidateVisual();
                        }
                    }
                    else if (widget is Widgets.StraitLineWidget sLine)
                    {
                        if (Globals.MainWindow.rtbtnAutoHideStraitLine.IsChecked == true)
                        {
                            sLine.IsPresentating = true;
                            sLine.StartPresentateAdorner.Visibility = Visibility.Visible;
                            sLine.StartPresentateAdorner.InvalidateVisual();
                            sLine.EndPresentateAdorner.Visibility = Visibility.Visible;
                            sLine.EndPresentateAdorner.InvalidateVisual();
                        }
                    }
                }
            }
        }

        private void ShowLinkedLines()
        {
            if (this.editorManager == null) return;
            var pages = this.editorManager.GetAllPageEditors();
            if (pages == null || pages.Count <= 0) return;

            foreach (var page in pages)
            {
                var widgets = page.GetAllWidgets();
                if (widgets == null || widgets.Count <= 0) continue;

                foreach (var widget in widgets)
                {
                    if (widget is Widgets.BezierLineWidget bLine)
                    {
                        bLine.IsPresentating = false;
                        bLine.StartPresentateAdorner.Visibility = Visibility.Hidden;
                        bLine.StartPresentateAdorner.InvalidateVisual();
                        bLine.EndPresentateAdorner.Visibility = Visibility.Hidden;
                        bLine.EndPresentateAdorner.InvalidateVisual();
                    }
                    else if (widget is Widgets.PolyLineWidget pLine)
                    {
                        pLine.IsPresentating = false;
                        pLine.StartPresentateAdorner.Visibility = Visibility.Hidden;
                        pLine.StartPresentateAdorner.InvalidateVisual();
                        pLine.EndPresentateAdorner.Visibility = Visibility.Hidden;
                        pLine.EndPresentateAdorner.InvalidateVisual();
                    }
                    else if (widget is Widgets.StraitLineWidget sLine)
                    {
                        sLine.IsPresentating = false;
                        sLine.StartPresentateAdorner.Visibility = Visibility.Hidden;
                        sLine.StartPresentateAdorner.InvalidateVisual();
                        sLine.EndPresentateAdorner.Visibility = Visibility.Hidden;
                        sLine.EndPresentateAdorner.InvalidateVisual();
                    }
                }
            }
        }

        /// <summary>
        /// 此方法用于在演示之前将所有“备注文本”不为空的部件隐藏起来。
        /// 然后，到这个演示区的时候，先显示所以不带备注文本的部件；
        /// 按下PageDown后再显示第一个带备注文本的部件。
        /// </summary>
        private void HideAllWidgetsWithCommentText()
        {
            if (this.editorManager == null) return;
            var pages = this.editorManager.GetAllPageEditors();
            if (pages == null || pages.Count <= 0) return;

            foreach (var page in pages)
            {
                var widgets = page.GetAllWidgets();
                if (widgets == null || widgets.Count <= 0) continue;

                foreach (var widget in widgets)
                {
                    if (string.IsNullOrEmpty(widget.CommentText) == false)
                    {
                        widget.Visibility = Visibility.Hidden;
                    }
                }
            }
        }

        /// <summary>
        /// 此方法用以在演示完成后显示所有被隐藏的带备注文本的部件。
        /// </summary>
        private void ShowAllWidgetsWithCommentText()
        {
            if (this.editorManager == null) return;
            var pages = this.editorManager.GetAllPageEditors();
            if (pages == null || pages.Count <= 0) return;

            foreach (var page in pages)
            {
                var widgets = page.GetAllWidgets();
                if (widgets == null || widgets.Count <= 0) continue;

                foreach (var widget in widgets)
                {
                    if (string.IsNullOrEmpty(widget.CommentText) == false &&
                        widget.Visibility != Visibility.Visible)
                    {
                        widget.Visibility = Visibility.Visible;
                    }
                }
            }
        }

        private List<Widget> presentatingWidgets = null;

        public void PresentateNextByPath()
        {
            if (IsPresentatingByPath == false) return;

            if (presentatingWidgets == null || presentatingWidgets.Count <= 0)
            {
                presentationPoint++;
                PresentateByPath(presentationPoint);
            }
            else
            {
                //TODO:这里可以考虑用动画效果
                presentatingWidgets[0].Visibility = Visibility.Visible;
                presentatingWidgets.RemoveAt(0);
            }
        }

        /// <summary>
        /// 这两个列表用于在演示时记录临时被切换了“填空模式”和“显示/隐藏文本”状态的部件。
        /// </summary>
        internal List<Widget> presentationHidedTextWidgets = new List<Widget>();
        internal List<Widget> presentationFillBlankWidgets = new List<Widget>();
        /// <summary>
        /// 如果当前没有定义任何一个演示区，就将页面本身当作演示区，为每个页面添加一个临时的演示区域并覆盖整个页面。
        /// 演示结束时会自动移除之，不会出现在撤销列表中。
        /// </summary>
        internal List<RectangleWidget> tempPresentationAreas = new List<RectangleWidget>();

        /// <summary>
        /// 跳转到下一个演示区之前，先显示当前演示区内部所有被标记为“隐藏文本”的部件中的文本。
        /// </summary>
        /// <returns></returns>
        internal bool PresentateText()
        {
            var point = presentationPoint;
            if (point < 0 || point >= presentationAreas.Count) return false;

            var area = presentationAreas[point];
            var hasTextHidededWidget = false;
            foreach (var widget in area.MasterEditor.GetWidgetsInArea(area.RealRect, true))
            {
                if (widget.IsTextVisible == false)
                {
                    hasTextHidededWidget = true;
                    widget.IsTextVisible = true;  // 不涉及撤销记录列表，只是临时更改
                    if (presentationHidedTextWidgets.Contains(widget) == false)
                        presentationHidedTextWidgets.Add(widget);
                }

                if (widget.FillBlankMode == true &&
                    widget.HasFillBlanks == true &&
                    widget.TitleLevel != Enums.TitleStyle.Normal)
                {
                    hasTextHidededWidget = true;
                    widget.FillBlankMode = false; // 显示填空文本
                    if (presentationFillBlankWidgets.Contains(widget) == false)
                        presentationFillBlankWidgets.Add(widget);
                }
            }
            return hasTextHidededWidget;
        }

        public void PresentatePreviewByPath()
        {
            if (IsPresentatingByPath == false) return;

            presentationPoint--;
            PresentateByPath(presentationPoint);
        }

        private void RTBtnEndPresentationByPath_Click(object sender, RoutedEventArgs e)
        {
            ExitPresentationByPath();
        }

        private void ExitPresentationByPath()
        {
            #region 将按区域演示过程中显示隐藏文本的部件的文本恢复隐藏状态
            foreach (var widget in presentationHidedTextWidgets)
            {
                widget.IsTextVisible = false;
            }

            foreach (var widget in presentationFillBlankWidgets)
            {
                widget.FillBlankMode = true;
            }
            presentationHidedTextWidgets.Clear();
            presentationFillBlankWidgets.Clear();

            foreach (var rw in tempPresentationAreas)
            {
                rw.MasterEditor.RemoveWidget(rw);
            }
            tempPresentationAreas.Clear();
            #endregion

            RTBtnStartPresentationByPath.IsEnabled = true;
            presentationPoint = -1;
            isPresentatingByPath = false;

            foreach (var area in presentationAreas)
            {
                area.Visibility = Visibility.Visible;
            }

            SliderOfScale.Value = scaleSliderValueBeforePresentateByPath;
            scaleSliderValueBeforePresentateByPath = -1;

            this.MainScrollViewer.ScrollToHorizontalOffset(hOffsetBeforePresentateByPath);
            hOffsetBeforePresentateByPath = -1;

            this.MainScrollViewer.ScrollToVerticalOffset(vOffsetBeforePresentateByPath);
            vOffsetBeforePresentateByPath = -1;

            //设置文本显示方式为锐利，适应低分屏清晰地显示文本的需要
            TextOptions.SetTextFormattingMode(MainScrollViewer, TextFormattingMode.Display);

            foreach (var pe in this.editorManager.GetAllPageEditors())
            {
                pe.RefreshAssistGridForm();//该显示的显示
            }

            ShowAllWidgetsWithCommentText();

            // 显示演示状态下被自动隐藏的连接线。
            ShowLinkedLines();

            GridPresentationTools.Visibility = Visibility.Hidden;

            this.Ribbon.IsCollapsed = false;

            // 下面这些会造成演示时卡顿、点不开矩形部件标记文本等问题。
            //Ribbon.Visibility = Visibility.Visible;
            //rdRibbon.Height = new GridLength(1, GridUnitType.Auto);
            DPStatus.Visibility = Visibility.Visible;
            rdStatus.Height = new GridLength(28, GridUnitType.Pixel);

            //this.WindowStyle = WindowStyle.SingleBorderWindow;

            //这个不起作用！！！
            //this.MainScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
            //this.MainScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
        }

        /// <summary>
        /// Create a new animation to the x,y offset.  I beleive you need the have .NET 3.5 SP1 installed for
        /// this to work.  If you don't you can't call Storyboard.SetTarget.
        /// </summary>
        /// <param name="x">X position</param>
        /// <param name="y">Y position</param>
        internal void ScrollToPosition(bool withAnimation, double x, double y, bool ignoreX = false, bool ignoreY = false)
        {
            if (withAnimation)
            {
                #region 动画方式，有问题
                Storyboard sb = new Storyboard();

                if (ignoreY == false)
                {
                    DoubleAnimation vertAnim = new DoubleAnimation();
                    vertAnim.From = MainScrollViewer.VerticalOffset;
                    vertAnim.To = y;
                    vertAnim.DecelerationRatio = .2;
                    vertAnim.Duration = new Duration(TimeSpan.FromMilliseconds(1000));//1000毫秒
                    sb.Children.Add(vertAnim);
                    Storyboard.SetTarget(vertAnim, MainScrollViewer);
                    Storyboard.SetTargetProperty(vertAnim, new PropertyPath(AniScrollViewer.CurrentVerticalOffsetProperty));
                }

                if (ignoreX == false)
                {
                    DoubleAnimation horzAnim = new DoubleAnimation();
                    horzAnim.From = MainScrollViewer.HorizontalOffset;
                    horzAnim.To = x;
                    horzAnim.DecelerationRatio = .2;
                    horzAnim.Duration = new Duration(TimeSpan.FromMilliseconds(1000));

                    sb.Children.Add(horzAnim);
                    Storyboard.SetTarget(horzAnim, MainScrollViewer);
                    Storyboard.SetTargetProperty(horzAnim, new PropertyPath(AniScrollViewer.CurrentHorizontalOffsetProperty));
                }

                sb.Begin();
                #endregion 
            }
            else
            {
                this.MainScrollViewer.ScrollToHorizontalOffset(x);
                this.MainScrollViewer.ScrollToVerticalOffset(y);
            }
        }

        private void SearchPresentationAreas(string keyWords)
        {
            lbxFindPresentationAreas.Items.Clear();

            if (this.editorManager == null) return;

            var pages = this.editorManager.GetAllPageEditors();
            if (pages.Count <= 0) return;

            string findKeyWord = "";

            if (string.IsNullOrEmpty(keyWords) == false)
            {
                findKeyWord = keyWords;
            }

            foreach (PageEditor pageEditor in pages)
            {
                var widgets = pageEditor.GetAllWidgets();
                if (widgets.Count <= 0) continue;

                foreach (Widget w in widgets)
                {
                    var rectangle = w as Widgets.RectangleWidget;
                    if (rectangle == null || rectangle.IsPresentationArea == false) continue;

                    if (findKeyWord != "" && findKeyWord.ToLower() != rectangle.MarkText.ToLower()) continue;

                    var pal = new Widgets._RectangleWidget.PresentationAreaLabel(rectangle);
                    pal.PreviewMouseLeftButtonDown += Pal_PreviewMouseLeftButtonDown;
                    lbxFindPresentationAreas.Items.Add(pal);
                }
            }
        }

        private void Pal_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                var presentationAreaLabel = sender as Widgets._RectangleWidget.PresentationAreaLabel;
                if (presentationAreaLabel == null) return;

                PresentateArea(presentationAreaLabel.PresentationAreaWidget);
            }
        }

        private void TiFindPresentationAreaBorder_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                Commands.SearchPresentationAreasCommand.Execute(null);
            }
        }

        private void btnFindPresentationAreas_Click(object sender, RoutedEventArgs e)
        {
            FindPresentationAreasInDocument();
        }

        private void BtnPrePresentationArea_Click(object sender, RoutedEventArgs e)
        {
            PresentatePreviewByPath();
        }

        private void BtnPrePresentationExit_Click(object sender, RoutedEventArgs e)
        {
            RTBtnEndPresentationByPath_Click(sender, e);
        }

        private void BtnNextPresentationArea_Click(object sender, RoutedEventArgs e)
        {
            //如果发现当前区域内有隐藏文本的部件，显示其文本
            //如果当前区域内没有隐藏文本的部件，直接转移显示下一个演示区域。
            var shownHidedText = PresentateText();
            if (shownHidedText == false)
            {
                PresentateNextByPath();
            }
        }

        private void ImgStartPresentateAreas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            RTBtnStartPresentationByPath_Click(sender, e);
        }

        private void BtnLoadDataFromExcel_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();//首先根据打开文件对话框，选择excel表格
            if (File.Exists(editorManager.FullPathOfDiskFile))
            {
                var fi = new FileInfo(editorManager.FullPathOfDiskFile);
                ofd.InitialDirectory = fi.Directory.FullName;
            }
            ofd.Filter = "Excel 97－2003 文档(*.xls)|*.xls";//打开文件对话框筛选器
            string strPath;//文件完整的路径名
            if (ofd.ShowDialog() == true)
            {
                tbExcelFilePath.Text = ofd.FileName;
                strPath = ofd.FileName;
                LoadExcelData(strPath);
            }
        }

        private void LoadExcelData(string strPath)
        {
            try
            {
                //string strCon = "Provider=Microsoft.Jet.OleDb.4.0;data source=" + FileFullPath + ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1'"; //此连接只能操作Excel2007之前(.xls)文件
                //string strCon = "Provider = Microsoft.Ace.OleDb.12.0;data source=" + strPath + "; Extended Properties='Excel 12.0;HDR=NO;IMEX=1'"; //此连接可以操作.xls与.xlsx文件
                // 很遗憾，需要安装数据访问驱动。

                string strCon = "provider=microsoft.jet.oledb.4.0;data source=" + strPath + ";extended properties=excel 8.0";//关键是红色区域
                using (OleDbConnection con = new OleDbConnection(strCon))
                {
                    //建立连接
                    con.Open();

                    DataTable dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                    var tableName = dt.Rows[0][2].ToString().Trim();

                    string strSql = $"select * from [{tableName}]";//表名的写法也应注意不同，对应的excel表为sheet1，在这里要在其后加美元符号$，并用中括号
                    OleDbCommand cmd = new OleDbCommand(strSql, con);//建立要执行的命令

                    OleDbDataAdapter da = new OleDbDataAdapter(cmd);//建立数据适配器
                    DataSet ds = new DataSet();//新建数据集
                    da.Fill(ds, tableName);//把数据适配器中的数据读到数据集中的一个表中（此处表名为shyman，可以任取表名）
                                           //指定datagridview1的数据源为数据集ds的第一张表（也就是shyman表），也可以写ds.Table["shyman"]

                    dgMain.Columns.Clear();
                    dt = ds.Tables[0];
                    dgMain.BeginInit();
                    dgMain.ItemsSource = dt.DefaultView;
                    dgMain.Items.Refresh();
                    dgMain.EndInit();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);//捕捉异常
            }
        }

        private void TbExcelFilePath_KeyDown(object sender, KeyEventArgs e)
        {
            if (File.Exists(tbExcelFilePath.Text))
                LoadExcelData(tbExcelFilePath.Text);
            else
            {
                LunarMessage.Warning("指定路径的 Excel 文件不存在！");
            }
        }

        private void RefreshFieldsOfWidgets()
        {
            var pages = editorManager.GetAllPageEditors();
            foreach (var page in pages)
            {
                var widgets = page.GetAllWidgets();
                foreach (var widget in widgets)
                {
                    widget.RefreshText();
                }
            }
        }

        private void DgMain_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            RefreshFieldsOfWidgets();
        }

        private void BtnOutputPageImage_Click(object sender, RoutedEventArgs e)
        {
            if (dgMain.Items.Count <= 0)
            {
                LunarMessage.Warning("数据表中没有可以使用的数据！");
                return;
            }

            double scale = ScaleValueConverter.GetNewScaleValue(Globals.MainWindow.SliderOfScale.Value);

            if (scale < 1)
            {
                MessageBoxResult r = MessageBox.Show("　　当前文档的缩放比例小于１，导出的图片文件可能比较模糊。要继续吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (r != MessageBoxResult.Yes) return;
            }

            var mainPage = editorManager.GetMainSelectedPageEditor();
            if (mainPage == null)
            {
                if (editorManager.PageCount <= 0)
                {
                    LunarMessage.Warning("没有页面可以导出图像!");
                    return;
                }

                editorManager.FirstPageEditor.IsMainSelected = true;
                mainPage = editorManager.FirstPageEditor;
            }

            if (mainPage == null)
            {
                LunarMessage.Warning("找不到可以导出图像文件的页面！");
                return;
            }

            var fullPathName = tbOutputImagesDirectoryPath.Text;
            if (Directory.Exists(fullPathName) == false)
            {
                LunarMessage.Warning("指定目录不存在！");
                return;
            }

            if (fullPathName.EndsWith("\\") == false) fullPathName += "\\";
            var fileName = dgMain.SelectedIndex.ToString("D4") + ".png";
            fullPathName += fileName;

            bool isPng = true;
            if (rdTiff.IsChecked == true)
            {
                isPng = false;
            }

            OutportMainPageToImageFileCommand.OutputMainPageToImage(editorManager.FullPathOfDiskFile, editorManager, mainPage, fullPathName, isPng, scale, false);

            tbxOutputImageResult.Text += $"第 {dgMain.SelectedIndex} 行对应页面图已导出。\r\n";
        }

        private void BtnSelectDirectoryForOutputImage_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            dialog.Description = "请选择导出目录：";
            if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;

            tbOutputImagesDirectoryPath.Text = dialog.SelectedPath;
            Globals.ConfigManager.Set("OutputImagesDirectoryPath", dialog.SelectedPath);
        }

        private void RdPng_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            rdTiff.IsChecked = false;
            rdPng.IsChecked = true;
        }

        private void RdTiff_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            rdTiff.IsChecked = true;
            rdPng.IsChecked = false;
        }

        private void DgMain_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            KeyStates ksLeftShift = Keyboard.GetKeyStates(Key.LeftShift);
            KeyStates ksRightShift = Keyboard.GetKeyStates(Key.RightShift);

            bool isShift = false;
            if ((ksLeftShift & KeyStates.Down) > 0 || (ksRightShift & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
            KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);

            bool isCtrl = false;
            if ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0)
            {
                isCtrl = true;
            }

            switch (e.Key)
            {
                case Key.OemTilde:
                    {
                        if (isCtrl && !isShift)
                        {
                            e.Handled = true;
                            BtnOutputPageImage_Click(sender, e);
                            if (dgMain.SelectedIndex < dgMain.Items.Count - 1)
                            {
                                dgMain.SelectedIndex += 1;
                                dgMain.Focus();
                            }
                        }
                        break;
                    }
            }
        }

        private void RTBtnShowPageNumber_Click(object sender, RoutedEventArgs e)
        {
            Commands.ShowPageNumberCommand.Execute();
        }

        private void cmiDeleteUserStyle_Click(object sender, RoutedEventArgs e)
        {
            var selStyleListItem = UserStylesListBox.SelectedItem as UserStyleListItem;
            if (selStyleListItem == null)
            {
                MessageBox.Show("请先选中要删除的样式！", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            try
            {
                var ws = selStyleListItem.WidgetStyleFileName;
                if (ws.ToLower().EndsWith(".txt") == false)
                    ws += ".txt";
                var path = Globals.PathOfUserStyles + ws;
                if (File.Exists(path) == true)
                {
                    var aw = MessageBox.Show("删除后不可恢复，真的要继续吗？", Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Question);
                    if (aw != MessageBoxResult.Yes) return;

                    File.Delete(Globals.PathOfUserStyles + ws);
                }
                else
                {
                    MessageBox.Show("磁盘上没这个样式文件，可能已删除！", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                }

                if (UserStylesListBox.Items.Contains(selStyleListItem))
                {
                    UserStylesListBox.Items.Remove(selStyleListItem);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }


        private void RBtnLoadPdfFileAsTempBackground_Click(object sender, RoutedEventArgs e)
        {
            var ae = this.editorManager.GetMainSelectedPageEditor();
            if (ae == null) return;

            var dialog = new OpenFileDialog()
            {
                Filter = "PDF 文档(*.pdf)|*.pdf",
            };

            if (dialog.ShowDialog().GetValueOrDefault())
            {
                string filePath = dialog.FileName;

                try
                {
                    MoonPdfPanel mpp;

                    if (ae.PdfPanel != null)
                    {
                        mpp = ae.PdfPanel;
                    }
                    else
                    {
                        mpp = new MoonPdfPanel()
                        {
                            ViewType = ViewType.SinglePage,
                            PageMargin = new Thickness(0),
                            Padding = new Thickness(0),
                        };
                    }

                    ae.PdfPanel = mpp;
                    if (ae.BaseCanvas.Children.Contains(mpp) == false)
                    {
                        ae.BaseCanvas.Children.Insert(0, mpp);
                        Canvas.SetLeft(mpp, -10);
                        Canvas.SetTop(mpp, -10);
                    }

                    ae.PdfFilePath = filePath;
                    mpp.OpenFile(filePath);
                    mpp.GotoPage(1);
                    mpp.ZoomStep = 0.01;

                    if (ae.PaperDirection == Orientation.Horizontal)
                    {
                        mpp.Height = ae.PaperSize.ShortSideWPFUnit + 20;
                        mpp.Width = ae.PaperSize.LongSideWPFUnit + 20;

                        //mpp.InvalidateVisual();   // 这个是没用的，必须用 InvalidateArrange();
                        // 这个不能少，否则 ZoomToWidth() 会抛出异常。
                        mpp.InvalidateArrange();
                        mpp.UpdateLayout();

                        //if (mpp.Width == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                        //{
                        //    mpp.Zoom(1.33);
                        //}
                        //else if (mpp.Width == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                        //{
                        //    mpp.Zoom(1.88);
                        //}
                    }
                    else
                    {
                        mpp.Width = ae.PaperSize.ShortSideWPFUnit + 20;
                        mpp.Height = ae.PaperSize.LongSideWPFUnit + 20;

                        // 这个不能少，否则 ZoomToWidth() 会抛出异常。
                        mpp.InvalidateArrange();
                        mpp.UpdateLayout();

                        //if (mpp.Height == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                        //{
                        //    mpp.Zoom(1.33);
                        //}
                        //else if (mpp.Height == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                        //{
                        //    mpp.Zoom(1.88);
                        //}
                    }
                    //mpp.Zoom(1.88);  // 适合A3
                    //mpp.Zoom(1.33);  // 适合A4
                    mpp.ZoomToWidth();
                }
                catch (Exception ex)
                {
                    LunarMessage.Warning(ex.Message);
                }
            }
        }

        private void RBtnLoadPdfZoomIn_Click(object sender, RoutedEventArgs e)
        {
            var ae = this.editorManager.GetMainSelectedPageEditor();
            if (ae == null || ae.PdfPanel == null) return;

            ae.PdfPanel.ZoomIn();
        }

        private void RBtnLoadPdfZoomOut_Click(object sender, RoutedEventArgs e)
        {
            var ae = this.editorManager.GetMainSelectedPageEditor();
            if (ae == null || ae.PdfPanel == null) return;

            ae.PdfPanel.ZoomOut();
        }

        private void RBtnGoToPDFPage_Click(object sender, RoutedEventArgs e)
        {
            var ae = this.editorManager.GetMainSelectedPageEditor();
            if (ae == null || ae.PdfPanel == null)
            {
                LunarMessage.Warning("没找到活动编辑器，或者活动编辑器没有载入PDF页面。");
                return;
            }

            try
            {
                var inputText = InputBox.Show(Globals.AppName, "请输入PDF页号：",
                    ae.PdfPanel.GetCurrentPageNumber().ToString(), false, null, false);
                if (int.TryParse(inputText, out int result))
                {
                    ae.PdfPanel.GotoPage(result);
                }
                else
                {
                    LunarMessage.Warning("请输入数字！");
                }
            }
            catch (Exception ex)
            {
                LunarMessage.Warning(ex.Message);
            }
        }

        private void RBtnAddPDFPage_Click(object sender, RoutedEventArgs e)
        {
            var oldae = editorManager.GetMainSelectedPageEditor();
            if (oldae == null || oldae.PdfPanel == null)
            {
                LunarMessage.Warning("没找到活动编辑器，或者活动编辑器未载入PDF文档。");
                return;
            }

            var oldPageNum = oldae.PdfPanel.GetCurrentPageNumber();
            if (oldPageNum >= oldae.PdfPanel.TotalPages)
            {
                LunarMessage.Warning("已经是最后一页。");
                return;
            }

            var filePath = oldae.PdfFilePath;

            Commands.InsertNewPageEditorCommand.Execute();

            var ae = this.editorManager.GetMainSelectedPageEditor();
            if (ae == null) return;

            try
            {
                MoonPdfPanel mpp;

                if (ae.PdfPanel != null)
                {
                    mpp = ae.PdfPanel;
                }
                else
                {
                    mpp = new MoonPdfPanel()
                    {
                        ViewType = ViewType.SinglePage,
                        PageMargin = new Thickness(0),
                        Padding = new Thickness(0),
                    };
                }

                ae.PdfPanel = mpp;

                if (ae.BaseCanvas.Children.Contains(mpp) == false)
                {
                    ae.BaseCanvas.Children.Insert(0, mpp);
                    Canvas.SetLeft(mpp, -10);
                    Canvas.SetTop(mpp, -10);
                }

                ae.PdfFilePath = filePath;
                mpp.OpenFile(filePath);
                mpp.GotoPage(oldPageNum + 1);
                mpp.ZoomStep = 0.01;

                if (ae.PaperDirection == Orientation.Horizontal)
                {
                    mpp.Height = ae.PaperSize.ShortSideWPFUnit + 20;
                    mpp.Width = ae.PaperSize.LongSideWPFUnit + 20;

                    // 必面用下面这个，否则 ZoomToWidth() 会抛出异常；InvalidateViausl() 无效！
                    mpp.InvalidateArrange();
                    mpp.UpdateLayout();

                    //if (mpp.Width == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                    //{
                    //    mpp.Zoom(1.33);
                    //}
                    //else if (mpp.Width == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                    //{
                    //    mpp.Zoom(1.88);
                    //}
                }
                else
                {
                    mpp.Width = ae.PaperSize.ShortSideWPFUnit + 20;
                    mpp.Height = ae.PaperSize.LongSideWPFUnit + 20;

                    // 必面用下面这个，否则 ZoomToWidth() 会抛出异常；InvalidateViausl() 无效！
                    mpp.InvalidateArrange();
                    mpp.UpdateLayout();

                    //if (mpp.Height == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                    //{
                    //    mpp.Zoom(1.33);
                    //}
                    //else if (mpp.Height == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                    //{
                    //    mpp.Zoom(1.88);
                    //}
                }

                mpp.ZoomToWidth();
            }
            catch (Exception ex)
            {
                LunarMessage.Warning(ex.Message);
            }
        }

        private void RBtnAddPDFFile_Click(object sender, RoutedEventArgs e)
        {
            var oldae = editorManager.GetMainSelectedPageEditor();
            if (oldae == null || oldae.PdfPanel == null)
            {
                LunarMessage.Warning("没找到活动编辑器，或者活动编辑器未载入PDF文档。");
                return;
            }

            try
            {
                var oldPathInfo = new FileInfo(oldae.PdfFilePath);
                var reg = new Regex(@"\d{1,}\.pdf", RegexOptions.IgnoreCase);
                var match = reg.Match(oldPathInfo.Name);
                if (match.Success == false)
                {
                    LunarMessage.Warning("这里使用的PDF文档只能以纯数字字符命名（并以 pdf 为后缀名）。");
                    return;
                }

                if (int.TryParse(oldPathInfo.Name.Substring(0, oldPathInfo.Name.Length - 4), out int oldNum) == false)
                {
                    LunarMessage.Warning("已载入的 PDF 文档名转换为数字时出错。");
                    return;
                }

                var newPdfPath = oldPathInfo.Directory.FullName + "\\" + (oldNum + 1).ToString($"d{oldPathInfo.Name.Length - 4}") + ".pdf";


                Commands.InsertNewPageEditorCommand.Execute();

                var ae = this.editorManager.GetMainSelectedPageEditor();
                if (ae == null) return;

                MoonPdfPanel mpp;

                if (ae.PdfPanel != null)
                {
                    mpp = ae.PdfPanel;
                }
                else
                {
                    mpp = new MoonPdfPanel()
                    {
                        ViewType = ViewType.SinglePage,
                        PageMargin = new Thickness(0),
                        Padding = new Thickness(0),
                    };
                }

                ae.PdfPanel = mpp;
                if (ae.BaseCanvas.Children.Contains(mpp) == false)
                {
                    ae.BaseCanvas.Children.Insert(0, mpp);
                    Canvas.SetLeft(mpp, -10);
                    Canvas.SetTop(mpp, -10);
                }

                ae.PdfFilePath = newPdfPath;
                mpp.OpenFile(newPdfPath);
                mpp.GotoPage(1);
                mpp.ZoomStep = 0.01;

                if (ae.PaperDirection == Orientation.Horizontal)
                {
                    mpp.Height = ae.PaperSize.ShortSideWPFUnit + 20;
                    mpp.Width = ae.PaperSize.LongSideWPFUnit + 20;

                    // 必面用下面这个，否则 ZoomToWidth() 会抛出异常；InvalidateViausl() 无效！
                    mpp.InvalidateArrange();
                    mpp.UpdateLayout();

                    //if (mpp.Width == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                    //{
                    //    mpp.Zoom(1.33);
                    //}
                    //else if (mpp.Width == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                    //{
                    //    mpp.Zoom(1.88);
                    //}
                }
                else
                {
                    mpp.Width = ae.PaperSize.ShortSideWPFUnit + 20;
                    mpp.Height = ae.PaperSize.LongSideWPFUnit + 20;

                    // 必面用下面这个，否则 ZoomToWidth() 会抛出异常；InvalidateViausl() 无效！
                    mpp.InvalidateArrange();
                    mpp.UpdateLayout();
                    //if (mpp.Height == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                    //{
                    //    mpp.Zoom(1.33);
                    //}
                    //else if (mpp.Height == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                    //{
                    //    mpp.Zoom(1.88);
                    //}
                }

                mpp.ZoomToWidth();
            }
            catch (Exception ex)
            {
                LunarMessage.Warning(ex.Message);
            }
        }

        private void RBtnLoadAllPDFFiles_Click(object sender, RoutedEventArgs e)
        {
            var ae = this.editorManager.GetMainSelectedPageEditor();
            if (ae == null) return;

            //if (ae.PaperSizeText != "A3")
            //{
            //    var result = MessageBox.Show("这个缩放比例适合A3，要自动更改吗？", Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Question);

            //    //if (result != MessageBoxResult.Yes) return;

            //    if (result == MessageBoxResult.Yes)
            //    {
            //        Commands.SetPaperSizeCommand.Execute("A3");
            //    }
            //}

            var dialog = new OpenFileDialog()
            {
                Filter = "PDF 文档(*.pdf)|*.pdf",
            };

            if (dialog.ShowDialog().GetValueOrDefault())
            {
                var pathInfo = new FileInfo(dialog.FileName);
                var reg = new Regex(@"(?<=(.{0,}))\d{1,}(?=(\.pdf))", RegexOptions.IgnoreCase);
                var match = reg.Match(pathInfo.Name);
                if (match.Success == false)
                {
                    LunarMessage.Warning("这里使用的PDF文档只能以纯数字字符命名（并以 pdf 为后缀名）。");
                    return;
                }

                if (int.TryParse(match.Value, out int fstFileNameNum) == false)
                {
                    LunarMessage.Warning("已载入的 PDF 文档名转换为数字时出错。");
                    return;
                }

                string filePath = dialog.FileName;

                try
                {
                    MoonPdfPanel mpp;

                    if (ae.PdfPanel != null)
                    {
                        mpp = ae.PdfPanel;
                    }
                    else
                    {
                        mpp = new MoonPdfPanel()
                        {
                            ViewType = ViewType.SinglePage,
                            PageMargin = new Thickness(0),
                            Padding = new Thickness(0),
                        };
                    }

                    ae.PdfPanel = mpp;
                    if (ae.BaseCanvas.Children.Contains(mpp) == false)
                    {
                        ae.BaseCanvas.Children.Insert(0, mpp);
                        Canvas.SetLeft(mpp, -10);
                        Canvas.SetTop(mpp, -10);
                    }

                    ae.PdfFilePath = filePath;
                    mpp.OpenFile(filePath);
                    mpp.GotoPage(1);
                    mpp.ZoomStep = 0.01;

                    if (ae.PaperDirection == Orientation.Horizontal)
                    {
                        mpp.Height = ae.PaperSize.ShortSideWPFUnit + 20;
                        mpp.Width = ae.PaperSize.LongSideWPFUnit + 20;

                        // 必面用下面这个，否则 ZoomToWidth() 会抛出异常；InvalidateViausl() 无效！
                        mpp.InvalidateArrange();
                        mpp.UpdateLayout();
                        //if (mpp.Width == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                        //{
                        //    mpp.Zoom(1.33);
                        //}
                        //else if (mpp.Width == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                        //{
                        //    mpp.Zoom(1.88);
                        //}
                    }
                    else
                    {
                        mpp.Width = ae.PaperSize.ShortSideWPFUnit + 20;
                        mpp.Height = ae.PaperSize.LongSideWPFUnit + 20;

                        // 必面用下面这个，否则 ZoomToWidth() 会抛出异常；InvalidateViausl() 无效！
                        mpp.InvalidateArrange();
                        mpp.UpdateLayout();
                        //if (mpp.Height == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                        //{
                        //    mpp.Zoom(1.33);
                        //}
                        //else if (mpp.Height == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                        //{
                        //    mpp.Zoom(1.88);
                        //}
                    }
                    mpp.ZoomToWidth();

                    var ne = ae.NextEditor;
                    var prePdfFilePath = ae.PdfFilePath;
                    while (ne != null)
                    {
                        var prePathInfo = new FileInfo(prePdfFilePath);
                        var match2 = reg.Match(prePathInfo.Name);
                        if (match2.Success == false)
                        {
                            LunarMessage.Warning("这里使用的PDF文档只能以纯数字字符命名（并以 pdf 为后缀名）。");
                            return;
                        }

                        if (int.TryParse(match2.Value, out int preNum) == false)
                        {
                            LunarMessage.Warning("已载入的 PDF 文档名转换为数字时出错。");
                            return;
                        }

                        var newPdfPath = prePathInfo.Directory.FullName + "\\" + (preNum + 1).ToString($"d{prePathInfo.Name.Length - 4}") + ".pdf";
                        if (File.Exists(newPdfPath) == false)
                        {
                            newPdfPath = prePathInfo.Directory.FullName + "\\" + (preNum + 1).ToString() + ".pdf";
                            if (File.Exists(newPdfPath) == false) break;  // 两种命名方式都不对。
                        }

                        MoonPdfPanel mpp2;

                        if (ne.PdfPanel != null)
                        {
                            mpp2 = ne.PdfPanel;
                        }
                        else
                        {
                            mpp2 = new MoonPdfPanel()
                            {
                                ViewType = ViewType.SinglePage,
                                PageMargin = new Thickness(0),
                                Padding = new Thickness(0),
                            };
                        }

                        ne.PdfPanel = mpp2;

                        if (ne.BaseCanvas.Children.Contains(mpp2) == false)
                        {
                            ne.BaseCanvas.Children.Insert(0, mpp2);
                            Canvas.SetLeft(mpp2, -10);
                            Canvas.SetTop(mpp2, -10);
                        }

                        ne.PdfFilePath = newPdfPath;
                        mpp2.OpenFile(newPdfPath);
                        mpp2.GotoPage(1);
                        mpp2.ZoomStep = 0.01;

                        if (ne.PaperDirection == Orientation.Horizontal)
                        {
                            mpp2.Height = ne.PaperSize.ShortSideWPFUnit + 20;
                            mpp2.Width = ne.PaperSize.LongSideWPFUnit + 20;

                            // 必面用下面这个，否则 ZoomToWidth() 会抛出异常；InvalidateViausl() 无效！
                            mpp2.InvalidateArrange();
                            mpp2.UpdateLayout();
                            //if (mpp2.Width == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                            //{
                            //    mpp2.Zoom(1.33);
                            //}
                            //else if (mpp2.Width == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                            //{
                            //    mpp2.Zoom(1.88);
                            //}
                        }
                        else
                        {
                            mpp2.Width = ne.PaperSize.ShortSideWPFUnit + 20;
                            mpp2.Height = ne.PaperSize.LongSideWPFUnit + 20;

                            // 必面用下面这个，否则 ZoomToWidth() 会抛出异常；InvalidateViausl() 无效！
                            mpp2.InvalidateArrange();
                            mpp2.UpdateLayout();
                            //if (mpp2.Height == PaperInfo.GetPaperInfo("A4").LongSideWPFUnit)
                            //{
                            //    mpp2.Zoom(1.33);
                            //}
                            //else if (mpp2.Height == PaperInfo.GetPaperInfo("A3").LongSideWPFUnit)
                            //{
                            //    mpp2.Zoom(1.88);
                            //}
                        }
                        mpp2.ZoomToWidth();

                        prePdfFilePath = ne.PdfFilePath;
                        ne = ne.NextEditor;
                    }
                }
                catch (Exception ex)
                {
                    LunarMessage.Warning(ex.Message);
                }
            }
        }

        private void RBtnLoadAllImageFiles_Click(object sender, RoutedEventArgs e)
        {
            var ae = this.editorManager.GetMainSelectedPageEditor();
            if (ae == null) return;

            if (ae.PaperSizeText != "A3")
            {
                var result = MessageBox.Show("这个缩放比例适合A3，要自动更改吗？", Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Question);

                //if (result != MessageBoxResult.Yes) return;
                Commands.SetPaperSizeCommand.Execute("A3");
            }

            var dialog = new OpenFileDialog()
            {
                Filter = "Jpg图像文件(*.jpg)|*.jpg|PNG 图像文件(*.png)|*.png",
            };

            if (dialog.ShowDialog().GetValueOrDefault())
            {
                var pathInfo = new FileInfo(dialog.FileName);
                var reg = new Regex(@"(?<=(.{0,}?))\d{1,}(?=(\.((png)|(jpg)|(jpeg))))", RegexOptions.IgnoreCase);
                var match = reg.Match(pathInfo.Name);
                if (match.Success == false)
                {
                    LunarMessage.Warning("这里使用的图像文件名必须以数字结尾。");
                    return;
                }

                if (int.TryParse(match.Value, out int fstFileNameNum) == false)
                {
                    LunarMessage.Warning("已载入的图像文件名转换为数字时出错。");
                    return;
                }

                string filePath = dialog.FileName;

                try
                {
                    Image img;

                    if (ae.BackgroundImage != null)
                    {
                        img = ae.BackgroundImage;
                    }
                    else
                    {
                        img = new Image();
                    }

                    if (ae.PaperDirection == Orientation.Horizontal)
                    {
                        img.Height = ae.PaperSize.ShortSideWPFUnit;
                        img.Width = ae.PaperSize.LongSideWPFUnit;
                    }
                    else
                    {
                        img.Width = ae.PaperSize.ShortSideWPFUnit;
                        img.Height = ae.PaperSize.LongSideWPFUnit;
                    }

                    ae.ImageFilePath = filePath;

                    var ext = new FileInfo(filePath).Extension;

                    // 载入图像文件
                    img.Source = Globals.LoadBitmapImageFromFile(filePath);

                    ae.BackgroundImage = img;
                    if (ae.BaseCanvas.Children.Contains(img) == false)
                    {
                        if (ae.PdfPanel != null && ae.BaseCanvas.Children.Contains(ae.PdfPanel))
                        {
                            ae.BaseCanvas.Children.Insert(1, img);   // Image 优先
                        }
                        else
                        {
                            ae.BaseCanvas.Children.Insert(0, img);
                        }
                    }

                    var ne = ae.NextEditor;
                    var preImgFilePath = ae.ImageFilePath;
                    while (ne != null)
                    {
                        var prePathInfo = new FileInfo(preImgFilePath);
                        var match2 = reg.Match(prePathInfo.Name);
                        if (match2.Success == false)
                        {
                            LunarMessage.Warning("这里使用的图像文文件必须以数字结尾。");
                            return;
                        }

                        if (int.TryParse(match2.Value, out int preNum) == false)
                        {
                            LunarMessage.Warning("已载入的图像名转换数字时出错。");
                            return;
                        }

                        var newImagePath = prePathInfo.Directory.FullName + "\\" +
                            prePathInfo.Name.Substring(0, match2.Index) +
                            (preNum + 1).ToString(match.Value.StartsWith("0") ? $"D{match.Value.Length}" : "") + ext;

                        if (File.Exists(newImagePath) == false)
                        {
                            break;
                        }

                        Image img2;

                        if (ne.BackgroundImage != null)
                        {
                            img2 = ne.BackgroundImage;
                        }
                        else
                        {
                            img2 = new Image();
                        }

                        if (ne.PaperDirection == Orientation.Horizontal)
                        {
                            img2.Height = ne.PaperSize.ShortSideWPFUnit;
                            img2.Width = ne.PaperSize.LongSideWPFUnit;
                        }
                        else
                        {
                            img2.Width = ne.PaperSize.ShortSideWPFUnit;
                            img2.Height = ne.PaperSize.LongSideWPFUnit;
                        }

                        ne.ImageFilePath = newImagePath;

                        img2.Source = Globals.LoadBitmapImageFromFile(newImagePath);

                        ne.BackgroundImage = img2;

                        if (ne.BaseCanvas.Children.Contains(img2) == false)
                        {
                            if (ne.PdfPanel != null && ne.BaseCanvas.Children.Contains(ne.PdfPanel))
                            {
                                ne.BaseCanvas.Children.Insert(1, img2);  // Image 优先
                            }
                            else
                            {
                                ne.BaseCanvas.Children.Insert(0, img2);
                            }
                        }

                        preImgFilePath = ne.ImageFilePath;
                        ne = ne.NextEditor;
                    }
                }
                catch (Exception ex)
                {
                    LunarMessage.Warning(ex.Message);
                }
            }
        }

        /// <summary>
        /// [用于调试]输出指定控件的模板文本。仅用于调试。
        /// </summary>
        /// <param name="ctrl"></param>
        /// <returns></returns>
        string GetTemplateXamlCode(Control ctrl)
        {
            FrameworkTemplate template = ctrl.Template;
            string xaml = "";
            if (template != null)
            {
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;
                settings.IndentChars = new string(' ', 4);
                settings.NewLineOnAttributes = true;
                StringBuilder strbuild = new StringBuilder();
                XmlWriter xmlwrite = XmlWriter.Create(strbuild, settings);
                try
                {
                    XamlWriter.Save(template, xmlwrite);
                    xaml = strbuild.ToString();
                }
                catch (Exception exc)
                {
                    xaml = exc.Message;
                }
            }
            else
            {
                xaml = "no template";
            }
            return xaml;
        }

        private void RBtnOutTemplate_Click(object sender, RoutedEventArgs e)
        {
            string templateText = GetTemplateXamlCode(RTBPresentation as Control);
            File.WriteAllText("D:\\RTBPresentation.txt", templateText);
            MessageBox.Show("控件模板文件已输出到：D:\\RTBPresentation.txt");
        }

        private WorkspaceManager workspaceManager;

        public WorkspaceManager WorkspaceManager { get { return workspaceManager; } }

        private void btnLoadLmeWorkspaceStruct_Click(object sender, RoutedEventArgs e)
        {

            LoadOrCreateWorkspace();
        }

        private void LoadOrCreateWorkspace()
        {
            //try
            //{
            if (System.IO.File.Exists(Globals.MainWindow.editorManager.FullPathOfDiskFile) == false)
            {
                MessageBox.Show("磁盘上找不到当前文件。请先保存当前文件！", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            var workspacePath = Globals.PathOfWorkspace;
            if (System.IO.Directory.Exists(workspacePath) == false || System.IO.File.Exists(workspacePath + "WorkspaceItems.xml") == false)
            {
                var workspaceItemFilePath = Globals.PathOfParentDirectory + "WorkspaceItems.xml";

                if (System.IO.File.Exists(workspaceItemFilePath) == false)
                {
                    var result = MessageBox.Show("尚未创建与文件同名的工作区目录，当前文件所在目录也不是个 LME 工作区。操作无法继续。\r\n\r\n要自动创建一个新工作区吗？", Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Question);
                    if (result != MessageBoxResult.Yes)
                        return;
                    System.IO.Directory.CreateDirectory(workspacePath);

                    result = MessageBox.Show("已自动创建同名目录。\r\n\r\n要尝试调用 Markdown To CHM(LME) 打开该目录作为工作区编写文档或添加资源吗？\r\n\r\n★Markdown To CHM(LME) 打开后，请重新执行本操作！！！", Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Question);
                    if (result != MessageBoxResult.Yes)
                        return;
                    OpenWorkspace(workspacePath);
                    workspaceManager.LoadWorkspaceFromXml(workspacePath + "WorkspaceItems.xml");
                }
                else
                {
                    workspaceManager.LoadWorkspaceFromXml(workspaceItemFilePath);
                }

                return;    // 要求用户重新点击此按钮！！！
            }

            workspaceManager.LoadWorkspaceFromXml(workspacePath + "WorkspaceItems.xml");
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show(ex.Message, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            //}
        }

        private void OpenWorkspace(string workspacePath = null)
        {
            if (string.IsNullOrWhiteSpace(workspacePath))
            {
                workspacePath = Globals.PathOfWorkspace;
                if (string.IsNullOrWhiteSpace(workspacePath))
                {
                    LoadOrCreateWorkspace();
                    return;
                }
                else
                {
                    if (System.IO.File.Exists(workspacePath + "WorkspaceItems.xml") == false)
                    {
                        try
                        {
                            var pdi = new System.IO.DirectoryInfo(workspacePath);
                            var parentPath = pdi.Parent.FullName;
                            if (parentPath.EndsWith("\\") == false)
                                parentPath += "\\";

                            var parentWorkspaceItemsXmlPath = parentPath + "WorkspaceItems.xml";

                            if (System.IO.File.Exists(parentWorkspaceItemsXmlPath) == false)
                            {
                                LoadOrCreateWorkspace();
                                return;
                            }

                            workspacePath = parentPath;
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }
                    }
                }
            }

            RegistryKey regSubKey;
            RegistryKey regKey = Registry.ClassesRoot;
            string strRegPath = @"directory\shell\用 Markdown To CHM 打开\command\";
            regSubKey = regKey.OpenSubKey(strRegPath);
            if (regSubKey == null)
            {
                MessageBox.Show("未能在此计算机上找到 Markdown To CHM(LME)，无法调用。", Globals.AppName,
                     MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            var regValue = regSubKey.GetValue("");
            string lmeInstalledPath = regValue.ToString();
            if (lmeInstalledPath.EndsWith(" %1"))
                lmeInstalledPath = lmeInstalledPath.Substring(0, lmeInstalledPath.Length - 3);

            System.Diagnostics.Process.Start(lmeInstalledPath, $"\"{workspacePath}\"");

        }

        public void GetLmeWorkspaceItems(object item, ref List<WorkspaceTreeViewItem> list)
        {
            if (list == null || item == null) return;

            var wtvi = item as WorkspaceTreeViewItem;
            if (wtvi == null) return;

            list.Add(wtvi);

            foreach (var subItem in wtvi.Items)
            {
                var subwtvi = subItem as WorkspaceTreeViewItem;
                if (subwtvi == null) continue;

                GetLmeWorkspaceItems(subwtvi, ref list);
            }
        }

        private void btnOpenWorkspace_Click(object sender, RoutedEventArgs e)
        {
            OpenWorkspace();
        }

        private void miSetWidgetBackImageLink_Click(object sender, RoutedEventArgs e)
        {
            if (tvWorkDirectory.Items.Count <= 0) return;

            var activeWtiv = tvWorkDirectory.Items[0] as WorkspaceTreeViewItem;
            if (activeWtiv == null) return;

            if (activeWtiv.IsSelected)
            {
                switch (activeWtiv.ItemType)
                {
                    case WorkspaceTreeViewItem.Type.Image:
                        {
                            Commands.SetWidgetBackImageLinkCommand.Execute(activeWtiv.RelativePath);
                            break;
                        }
                }
            }
            else
            {
                activeWtiv = WorkspaceTreeViewItem.GetActiveWorkspaceTreeViewItem(activeWtiv);
                if (activeWtiv != null)
                {
                    switch (activeWtiv.ItemType)
                    {
                        case WorkspaceTreeViewItem.Type.Image:
                            {
                                Commands.SetWidgetBackImageLinkCommand.Execute(activeWtiv.RelativePath);
                                break;
                            }
                    }
                }
                else
                {
                    MessageBox.Show("请选先选中某个图像条目！", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
        }

        private void btnTipOfFieldError_Click(object sender, RoutedEventArgs e)
        {
            var info = "　　有时会发现部分字段不能更新，是由于字体等样式设置“切断”了字段域造成的。\r\n" +
                "　　处置方式是将整个部件中的文本复制出来，然后清除部件中所有文本，再重新打开部件文本编辑器，把复制的文本粘贴回去并回车。\r\n" +
                "　　这就意味着：在对部件中的文本片段设置格式时，字段域（以两对半角花括号括起来的部分）必须统一格式。";

            MessageBox.Show(info, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Information);
        }
    }
}